glpapi12.c 79 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220
  1. /* glpapi12.c (basis factorization and simplex tableau routines) */
  2. /***********************************************************************
  3. * This code is part of GLPK (GNU Linear Programming Kit).
  4. *
  5. * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
  6. * 2009, 2010 Andrew Makhorin, Department for Applied Informatics,
  7. * Moscow Aviation Institute, Moscow, Russia. All rights reserved.
  8. * E-mail: <mao@gnu.org>.
  9. *
  10. * GLPK is free software: you can redistribute it and/or modify it
  11. * under the terms of the GNU General Public License as published by
  12. * the Free Software Foundation, either version 3 of the License, or
  13. * (at your option) any later version.
  14. *
  15. * GLPK is distributed in the hope that it will be useful, but WITHOUT
  16. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  17. * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
  18. * License for more details.
  19. *
  20. * You should have received a copy of the GNU General Public License
  21. * along with GLPK. If not, see <http://www.gnu.org/licenses/>.
  22. ***********************************************************************/
  23. #include "glpapi.h"
  24. /***********************************************************************
  25. * NAME
  26. *
  27. * glp_bf_exists - check if the basis factorization exists
  28. *
  29. * SYNOPSIS
  30. *
  31. * int glp_bf_exists(glp_prob *lp);
  32. *
  33. * RETURNS
  34. *
  35. * If the basis factorization for the current basis associated with
  36. * the specified problem object exists and therefore is available for
  37. * computations, the routine glp_bf_exists returns non-zero. Otherwise
  38. * the routine returns zero. */
  39. int glp_bf_exists(glp_prob *lp)
  40. { int ret;
  41. ret = (lp->m == 0 || lp->valid);
  42. return ret;
  43. }
  44. /***********************************************************************
  45. * NAME
  46. *
  47. * glp_factorize - compute the basis factorization
  48. *
  49. * SYNOPSIS
  50. *
  51. * int glp_factorize(glp_prob *lp);
  52. *
  53. * DESCRIPTION
  54. *
  55. * The routine glp_factorize computes the basis factorization for the
  56. * current basis associated with the specified problem object.
  57. *
  58. * RETURNS
  59. *
  60. * 0 The basis factorization has been successfully computed.
  61. *
  62. * GLP_EBADB
  63. * The basis matrix is invalid, i.e. the number of basic (auxiliary
  64. * and structural) variables differs from the number of rows in the
  65. * problem object.
  66. *
  67. * GLP_ESING
  68. * The basis matrix is singular within the working precision.
  69. *
  70. * GLP_ECOND
  71. * The basis matrix is ill-conditioned. */
  72. static int b_col(void *info, int j, int ind[], double val[])
  73. { glp_prob *lp = info;
  74. int m = lp->m;
  75. GLPAIJ *aij;
  76. int k, len;
  77. xassert(1 <= j && j <= m);
  78. /* determine the ordinal number of basic auxiliary or structural
  79. variable x[k] corresponding to basic variable xB[j] */
  80. k = lp->head[j];
  81. /* build j-th column of the basic matrix, which is k-th column of
  82. the scaled augmented matrix (I | -R*A*S) */
  83. if (k <= m)
  84. { /* x[k] is auxiliary variable */
  85. len = 1;
  86. ind[1] = k;
  87. val[1] = 1.0;
  88. }
  89. else
  90. { /* x[k] is structural variable */
  91. len = 0;
  92. for (aij = lp->col[k-m]->ptr; aij != NULL; aij = aij->c_next)
  93. { len++;
  94. ind[len] = aij->row->i;
  95. val[len] = - aij->row->rii * aij->val * aij->col->sjj;
  96. }
  97. }
  98. return len;
  99. }
  100. static void copy_bfcp(glp_prob *lp);
  101. int glp_factorize(glp_prob *lp)
  102. { int m = lp->m;
  103. int n = lp->n;
  104. GLPROW **row = lp->row;
  105. GLPCOL **col = lp->col;
  106. int *head = lp->head;
  107. int j, k, stat, ret;
  108. /* invalidate the basis factorization */
  109. lp->valid = 0;
  110. /* build the basis header */
  111. j = 0;
  112. for (k = 1; k <= m+n; k++)
  113. { if (k <= m)
  114. { stat = row[k]->stat;
  115. row[k]->bind = 0;
  116. }
  117. else
  118. { stat = col[k-m]->stat;
  119. col[k-m]->bind = 0;
  120. }
  121. if (stat == GLP_BS)
  122. { j++;
  123. if (j > m)
  124. { /* too many basic variables */
  125. ret = GLP_EBADB;
  126. goto fini;
  127. }
  128. head[j] = k;
  129. if (k <= m)
  130. row[k]->bind = j;
  131. else
  132. col[k-m]->bind = j;
  133. }
  134. }
  135. if (j < m)
  136. { /* too few basic variables */
  137. ret = GLP_EBADB;
  138. goto fini;
  139. }
  140. /* try to factorize the basis matrix */
  141. if (m > 0)
  142. { if (lp->bfd == NULL)
  143. { lp->bfd = bfd_create_it();
  144. copy_bfcp(lp);
  145. }
  146. switch (bfd_factorize(lp->bfd, m, lp->head, b_col, lp))
  147. { case 0:
  148. /* ok */
  149. break;
  150. case BFD_ESING:
  151. /* singular matrix */
  152. ret = GLP_ESING;
  153. goto fini;
  154. case BFD_ECOND:
  155. /* ill-conditioned matrix */
  156. ret = GLP_ECOND;
  157. goto fini;
  158. default:
  159. xassert(lp != lp);
  160. }
  161. lp->valid = 1;
  162. }
  163. /* factorization successful */
  164. ret = 0;
  165. fini: /* bring the return code to the calling program */
  166. return ret;
  167. }
  168. /***********************************************************************
  169. * NAME
  170. *
  171. * glp_bf_updated - check if the basis factorization has been updated
  172. *
  173. * SYNOPSIS
  174. *
  175. * int glp_bf_updated(glp_prob *lp);
  176. *
  177. * RETURNS
  178. *
  179. * If the basis factorization has been just computed from scratch, the
  180. * routine glp_bf_updated returns zero. Otherwise, if the factorization
  181. * has been updated one or more times, the routine returns non-zero. */
  182. int glp_bf_updated(glp_prob *lp)
  183. { int cnt;
  184. if (!(lp->m == 0 || lp->valid))
  185. xerror("glp_bf_update: basis factorization does not exist\n");
  186. #if 0 /* 15/XI-2009 */
  187. cnt = (lp->m == 0 ? 0 : lp->bfd->upd_cnt);
  188. #else
  189. cnt = (lp->m == 0 ? 0 : bfd_get_count(lp->bfd));
  190. #endif
  191. return cnt;
  192. }
  193. /***********************************************************************
  194. * NAME
  195. *
  196. * glp_get_bfcp - retrieve basis factorization control parameters
  197. *
  198. * SYNOPSIS
  199. *
  200. * void glp_get_bfcp(glp_prob *lp, glp_bfcp *parm);
  201. *
  202. * DESCRIPTION
  203. *
  204. * The routine glp_get_bfcp retrieves control parameters, which are
  205. * used on computing and updating the basis factorization associated
  206. * with the specified problem object.
  207. *
  208. * Current values of control parameters are stored by the routine in
  209. * a glp_bfcp structure, which the parameter parm points to. */
  210. void glp_get_bfcp(glp_prob *lp, glp_bfcp *parm)
  211. { glp_bfcp *bfcp = lp->bfcp;
  212. if (bfcp == NULL)
  213. { parm->type = GLP_BF_FT;
  214. parm->lu_size = 0;
  215. parm->piv_tol = 0.10;
  216. parm->piv_lim = 4;
  217. parm->suhl = GLP_ON;
  218. parm->eps_tol = 1e-15;
  219. parm->max_gro = 1e+10;
  220. parm->nfs_max = 100;
  221. parm->upd_tol = 1e-6;
  222. parm->nrs_max = 100;
  223. parm->rs_size = 0;
  224. }
  225. else
  226. memcpy(parm, bfcp, sizeof(glp_bfcp));
  227. return;
  228. }
  229. /***********************************************************************
  230. * NAME
  231. *
  232. * glp_set_bfcp - change basis factorization control parameters
  233. *
  234. * SYNOPSIS
  235. *
  236. * void glp_set_bfcp(glp_prob *lp, const glp_bfcp *parm);
  237. *
  238. * DESCRIPTION
  239. *
  240. * The routine glp_set_bfcp changes control parameters, which are used
  241. * by internal GLPK routines in computing and updating the basis
  242. * factorization associated with the specified problem object.
  243. *
  244. * New values of the control parameters should be passed in a structure
  245. * glp_bfcp, which the parameter parm points to.
  246. *
  247. * The parameter parm can be specified as NULL, in which case all
  248. * control parameters are reset to their default values. */
  249. #if 0 /* 15/XI-2009 */
  250. static void copy_bfcp(glp_prob *lp)
  251. { glp_bfcp _parm, *parm = &_parm;
  252. BFD *bfd = lp->bfd;
  253. glp_get_bfcp(lp, parm);
  254. xassert(bfd != NULL);
  255. bfd->type = parm->type;
  256. bfd->lu_size = parm->lu_size;
  257. bfd->piv_tol = parm->piv_tol;
  258. bfd->piv_lim = parm->piv_lim;
  259. bfd->suhl = parm->suhl;
  260. bfd->eps_tol = parm->eps_tol;
  261. bfd->max_gro = parm->max_gro;
  262. bfd->nfs_max = parm->nfs_max;
  263. bfd->upd_tol = parm->upd_tol;
  264. bfd->nrs_max = parm->nrs_max;
  265. bfd->rs_size = parm->rs_size;
  266. return;
  267. }
  268. #else
  269. static void copy_bfcp(glp_prob *lp)
  270. { glp_bfcp _parm, *parm = &_parm;
  271. glp_get_bfcp(lp, parm);
  272. bfd_set_parm(lp->bfd, parm);
  273. return;
  274. }
  275. #endif
  276. void glp_set_bfcp(glp_prob *lp, const glp_bfcp *parm)
  277. { glp_bfcp *bfcp = lp->bfcp;
  278. if (parm == NULL)
  279. { /* reset to default values */
  280. if (bfcp != NULL)
  281. xfree(bfcp), lp->bfcp = NULL;
  282. }
  283. else
  284. { /* set to specified values */
  285. if (bfcp == NULL)
  286. bfcp = lp->bfcp = xmalloc(sizeof(glp_bfcp));
  287. memcpy(bfcp, parm, sizeof(glp_bfcp));
  288. if (!(bfcp->type == GLP_BF_FT || bfcp->type == GLP_BF_BG ||
  289. bfcp->type == GLP_BF_GR))
  290. xerror("glp_set_bfcp: type = %d; invalid parameter\n",
  291. bfcp->type);
  292. if (bfcp->lu_size < 0)
  293. xerror("glp_set_bfcp: lu_size = %d; invalid parameter\n",
  294. bfcp->lu_size);
  295. if (!(0.0 < bfcp->piv_tol && bfcp->piv_tol < 1.0))
  296. xerror("glp_set_bfcp: piv_tol = %g; invalid parameter\n",
  297. bfcp->piv_tol);
  298. if (bfcp->piv_lim < 1)
  299. xerror("glp_set_bfcp: piv_lim = %d; invalid parameter\n",
  300. bfcp->piv_lim);
  301. if (!(bfcp->suhl == GLP_ON || bfcp->suhl == GLP_OFF))
  302. xerror("glp_set_bfcp: suhl = %d; invalid parameter\n",
  303. bfcp->suhl);
  304. if (!(0.0 <= bfcp->eps_tol && bfcp->eps_tol <= 1e-6))
  305. xerror("glp_set_bfcp: eps_tol = %g; invalid parameter\n",
  306. bfcp->eps_tol);
  307. if (bfcp->max_gro < 1.0)
  308. xerror("glp_set_bfcp: max_gro = %g; invalid parameter\n",
  309. bfcp->max_gro);
  310. if (!(1 <= bfcp->nfs_max && bfcp->nfs_max <= 32767))
  311. xerror("glp_set_bfcp: nfs_max = %d; invalid parameter\n",
  312. bfcp->nfs_max);
  313. if (!(0.0 < bfcp->upd_tol && bfcp->upd_tol < 1.0))
  314. xerror("glp_set_bfcp: upd_tol = %g; invalid parameter\n",
  315. bfcp->upd_tol);
  316. if (!(1 <= bfcp->nrs_max && bfcp->nrs_max <= 32767))
  317. xerror("glp_set_bfcp: nrs_max = %d; invalid parameter\n",
  318. bfcp->nrs_max);
  319. if (bfcp->rs_size < 0)
  320. xerror("glp_set_bfcp: rs_size = %d; invalid parameter\n",
  321. bfcp->nrs_max);
  322. if (bfcp->rs_size == 0)
  323. bfcp->rs_size = 20 * bfcp->nrs_max;
  324. }
  325. if (lp->bfd != NULL) copy_bfcp(lp);
  326. return;
  327. }
  328. /***********************************************************************
  329. * NAME
  330. *
  331. * glp_get_bhead - retrieve the basis header information
  332. *
  333. * SYNOPSIS
  334. *
  335. * int glp_get_bhead(glp_prob *lp, int k);
  336. *
  337. * DESCRIPTION
  338. *
  339. * The routine glp_get_bhead returns the basis header information for
  340. * the current basis associated with the specified problem object.
  341. *
  342. * RETURNS
  343. *
  344. * If xB[k], 1 <= k <= m, is i-th auxiliary variable (1 <= i <= m), the
  345. * routine returns i. Otherwise, if xB[k] is j-th structural variable
  346. * (1 <= j <= n), the routine returns m+j. Here m is the number of rows
  347. * and n is the number of columns in the problem object. */
  348. int glp_get_bhead(glp_prob *lp, int k)
  349. { if (!(lp->m == 0 || lp->valid))
  350. xerror("glp_get_bhead: basis factorization does not exist\n");
  351. if (!(1 <= k && k <= lp->m))
  352. xerror("glp_get_bhead: k = %d; index out of range\n", k);
  353. return lp->head[k];
  354. }
  355. /***********************************************************************
  356. * NAME
  357. *
  358. * glp_get_row_bind - retrieve row index in the basis header
  359. *
  360. * SYNOPSIS
  361. *
  362. * int glp_get_row_bind(glp_prob *lp, int i);
  363. *
  364. * RETURNS
  365. *
  366. * The routine glp_get_row_bind returns the index k of basic variable
  367. * xB[k], 1 <= k <= m, which is i-th auxiliary variable, 1 <= i <= m,
  368. * in the current basis associated with the specified problem object,
  369. * where m is the number of rows. However, if i-th auxiliary variable
  370. * is non-basic, the routine returns zero. */
  371. int glp_get_row_bind(glp_prob *lp, int i)
  372. { if (!(lp->m == 0 || lp->valid))
  373. xerror("glp_get_row_bind: basis factorization does not exist\n"
  374. );
  375. if (!(1 <= i && i <= lp->m))
  376. xerror("glp_get_row_bind: i = %d; row number out of range\n",
  377. i);
  378. return lp->row[i]->bind;
  379. }
  380. /***********************************************************************
  381. * NAME
  382. *
  383. * glp_get_col_bind - retrieve column index in the basis header
  384. *
  385. * SYNOPSIS
  386. *
  387. * int glp_get_col_bind(glp_prob *lp, int j);
  388. *
  389. * RETURNS
  390. *
  391. * The routine glp_get_col_bind returns the index k of basic variable
  392. * xB[k], 1 <= k <= m, which is j-th structural variable, 1 <= j <= n,
  393. * in the current basis associated with the specified problem object,
  394. * where m is the number of rows, n is the number of columns. However,
  395. * if j-th structural variable is non-basic, the routine returns zero.*/
  396. int glp_get_col_bind(glp_prob *lp, int j)
  397. { if (!(lp->m == 0 || lp->valid))
  398. xerror("glp_get_col_bind: basis factorization does not exist\n"
  399. );
  400. if (!(1 <= j && j <= lp->n))
  401. xerror("glp_get_col_bind: j = %d; column number out of range\n"
  402. , j);
  403. return lp->col[j]->bind;
  404. }
  405. /***********************************************************************
  406. * NAME
  407. *
  408. * glp_ftran - perform forward transformation (solve system B*x = b)
  409. *
  410. * SYNOPSIS
  411. *
  412. * void glp_ftran(glp_prob *lp, double x[]);
  413. *
  414. * DESCRIPTION
  415. *
  416. * The routine glp_ftran performs forward transformation, i.e. solves
  417. * the system B*x = b, where B is the basis matrix corresponding to the
  418. * current basis for the specified problem object, x is the vector of
  419. * unknowns to be computed, b is the vector of right-hand sides.
  420. *
  421. * On entry elements of the vector b should be stored in dense format
  422. * in locations x[1], ..., x[m], where m is the number of rows. On exit
  423. * the routine stores elements of the vector x in the same locations.
  424. *
  425. * SCALING/UNSCALING
  426. *
  427. * Let A~ = (I | -A) is the augmented constraint matrix of the original
  428. * (unscaled) problem. In the scaled LP problem instead the matrix A the
  429. * scaled matrix A" = R*A*S is actually used, so
  430. *
  431. * A~" = (I | A") = (I | R*A*S) = (R*I*inv(R) | R*A*S) =
  432. * (1)
  433. * = R*(I | A)*S~ = R*A~*S~,
  434. *
  435. * is the scaled augmented constraint matrix, where R and S are diagonal
  436. * scaling matrices used to scale rows and columns of the matrix A, and
  437. *
  438. * S~ = diag(inv(R) | S) (2)
  439. *
  440. * is an augmented diagonal scaling matrix.
  441. *
  442. * By definition:
  443. *
  444. * A~ = (B | N), (3)
  445. *
  446. * where B is the basic matrix, which consists of basic columns of the
  447. * augmented constraint matrix A~, and N is a matrix, which consists of
  448. * non-basic columns of A~. From (1) it follows that:
  449. *
  450. * A~" = (B" | N") = (R*B*SB | R*N*SN), (4)
  451. *
  452. * where SB and SN are parts of the augmented scaling matrix S~, which
  453. * correspond to basic and non-basic variables, respectively. Therefore
  454. *
  455. * B" = R*B*SB, (5)
  456. *
  457. * which is the scaled basis matrix. */
  458. void glp_ftran(glp_prob *lp, double x[])
  459. { int m = lp->m;
  460. GLPROW **row = lp->row;
  461. GLPCOL **col = lp->col;
  462. int i, k;
  463. /* B*x = b ===> (R*B*SB)*(inv(SB)*x) = R*b ===>
  464. B"*x" = b", where b" = R*b, x = SB*x" */
  465. if (!(m == 0 || lp->valid))
  466. xerror("glp_ftran: basis factorization does not exist\n");
  467. /* b" := R*b */
  468. for (i = 1; i <= m; i++)
  469. x[i] *= row[i]->rii;
  470. /* x" := inv(B")*b" */
  471. if (m > 0) bfd_ftran(lp->bfd, x);
  472. /* x := SB*x" */
  473. for (i = 1; i <= m; i++)
  474. { k = lp->head[i];
  475. if (k <= m)
  476. x[i] /= row[k]->rii;
  477. else
  478. x[i] *= col[k-m]->sjj;
  479. }
  480. return;
  481. }
  482. /***********************************************************************
  483. * NAME
  484. *
  485. * glp_btran - perform backward transformation (solve system B'*x = b)
  486. *
  487. * SYNOPSIS
  488. *
  489. * void glp_btran(glp_prob *lp, double x[]);
  490. *
  491. * DESCRIPTION
  492. *
  493. * The routine glp_btran performs backward transformation, i.e. solves
  494. * the system B'*x = b, where B' is a matrix transposed to the basis
  495. * matrix corresponding to the current basis for the specified problem
  496. * problem object, x is the vector of unknowns to be computed, b is the
  497. * vector of right-hand sides.
  498. *
  499. * On entry elements of the vector b should be stored in dense format
  500. * in locations x[1], ..., x[m], where m is the number of rows. On exit
  501. * the routine stores elements of the vector x in the same locations.
  502. *
  503. * SCALING/UNSCALING
  504. *
  505. * See comments to the routine glp_ftran. */
  506. void glp_btran(glp_prob *lp, double x[])
  507. { int m = lp->m;
  508. GLPROW **row = lp->row;
  509. GLPCOL **col = lp->col;
  510. int i, k;
  511. /* B'*x = b ===> (SB*B'*R)*(inv(R)*x) = SB*b ===>
  512. (B")'*x" = b", where b" = SB*b, x = R*x" */
  513. if (!(m == 0 || lp->valid))
  514. xerror("glp_btran: basis factorization does not exist\n");
  515. /* b" := SB*b */
  516. for (i = 1; i <= m; i++)
  517. { k = lp->head[i];
  518. if (k <= m)
  519. x[i] /= row[k]->rii;
  520. else
  521. x[i] *= col[k-m]->sjj;
  522. }
  523. /* x" := inv[(B")']*b" */
  524. if (m > 0) bfd_btran(lp->bfd, x);
  525. /* x := R*x" */
  526. for (i = 1; i <= m; i++)
  527. x[i] *= row[i]->rii;
  528. return;
  529. }
  530. /***********************************************************************
  531. * NAME
  532. *
  533. * glp_warm_up - "warm up" LP basis
  534. *
  535. * SYNOPSIS
  536. *
  537. * int glp_warm_up(glp_prob *P);
  538. *
  539. * DESCRIPTION
  540. *
  541. * The routine glp_warm_up "warms up" the LP basis for the specified
  542. * problem object using current statuses assigned to rows and columns
  543. * (that is, to auxiliary and structural variables).
  544. *
  545. * This operation includes computing factorization of the basis matrix
  546. * (if it does not exist), computing primal and dual components of basic
  547. * solution, and determining the solution status.
  548. *
  549. * RETURNS
  550. *
  551. * 0 The operation has been successfully performed.
  552. *
  553. * GLP_EBADB
  554. * The basis matrix is invalid, i.e. the number of basic (auxiliary
  555. * and structural) variables differs from the number of rows in the
  556. * problem object.
  557. *
  558. * GLP_ESING
  559. * The basis matrix is singular within the working precision.
  560. *
  561. * GLP_ECOND
  562. * The basis matrix is ill-conditioned. */
  563. int glp_warm_up(glp_prob *P)
  564. { GLPROW *row;
  565. GLPCOL *col;
  566. GLPAIJ *aij;
  567. int i, j, type, ret;
  568. double eps, temp, *work;
  569. /* invalidate basic solution */
  570. P->pbs_stat = P->dbs_stat = GLP_UNDEF;
  571. P->obj_val = 0.0;
  572. P->some = 0;
  573. for (i = 1; i <= P->m; i++)
  574. { row = P->row[i];
  575. row->prim = row->dual = 0.0;
  576. }
  577. for (j = 1; j <= P->n; j++)
  578. { col = P->col[j];
  579. col->prim = col->dual = 0.0;
  580. }
  581. /* compute the basis factorization, if necessary */
  582. if (!glp_bf_exists(P))
  583. { ret = glp_factorize(P);
  584. if (ret != 0) goto done;
  585. }
  586. /* allocate working array */
  587. work = xcalloc(1+P->m, sizeof(double));
  588. /* determine and store values of non-basic variables, compute
  589. vector (- N * xN) */
  590. for (i = 1; i <= P->m; i++)
  591. work[i] = 0.0;
  592. for (i = 1; i <= P->m; i++)
  593. { row = P->row[i];
  594. if (row->stat == GLP_BS)
  595. continue;
  596. else if (row->stat == GLP_NL)
  597. row->prim = row->lb;
  598. else if (row->stat == GLP_NU)
  599. row->prim = row->ub;
  600. else if (row->stat == GLP_NF)
  601. row->prim = 0.0;
  602. else if (row->stat == GLP_NS)
  603. row->prim = row->lb;
  604. else
  605. xassert(row != row);
  606. /* N[j] is i-th column of matrix (I|-A) */
  607. work[i] -= row->prim;
  608. }
  609. for (j = 1; j <= P->n; j++)
  610. { col = P->col[j];
  611. if (col->stat == GLP_BS)
  612. continue;
  613. else if (col->stat == GLP_NL)
  614. col->prim = col->lb;
  615. else if (col->stat == GLP_NU)
  616. col->prim = col->ub;
  617. else if (col->stat == GLP_NF)
  618. col->prim = 0.0;
  619. else if (col->stat == GLP_NS)
  620. col->prim = col->lb;
  621. else
  622. xassert(col != col);
  623. /* N[j] is (m+j)-th column of matrix (I|-A) */
  624. if (col->prim != 0.0)
  625. { for (aij = col->ptr; aij != NULL; aij = aij->c_next)
  626. work[aij->row->i] += aij->val * col->prim;
  627. }
  628. }
  629. /* compute vector of basic variables xB = - inv(B) * N * xN */
  630. glp_ftran(P, work);
  631. /* store values of basic variables, check primal feasibility */
  632. P->pbs_stat = GLP_FEAS;
  633. for (i = 1; i <= P->m; i++)
  634. { row = P->row[i];
  635. if (row->stat != GLP_BS)
  636. continue;
  637. row->prim = work[row->bind];
  638. type = row->type;
  639. if (type == GLP_LO || type == GLP_DB || type == GLP_FX)
  640. { eps = 1e-6 + 1e-9 * fabs(row->lb);
  641. if (row->prim < row->lb - eps)
  642. P->pbs_stat = GLP_INFEAS;
  643. }
  644. if (type == GLP_UP || type == GLP_DB || type == GLP_FX)
  645. { eps = 1e-6 + 1e-9 * fabs(row->ub);
  646. if (row->prim > row->ub + eps)
  647. P->pbs_stat = GLP_INFEAS;
  648. }
  649. }
  650. for (j = 1; j <= P->n; j++)
  651. { col = P->col[j];
  652. if (col->stat != GLP_BS)
  653. continue;
  654. col->prim = work[col->bind];
  655. type = col->type;
  656. if (type == GLP_LO || type == GLP_DB || type == GLP_FX)
  657. { eps = 1e-6 + 1e-9 * fabs(col->lb);
  658. if (col->prim < col->lb - eps)
  659. P->pbs_stat = GLP_INFEAS;
  660. }
  661. if (type == GLP_UP || type == GLP_DB || type == GLP_FX)
  662. { eps = 1e-6 + 1e-9 * fabs(col->ub);
  663. if (col->prim > col->ub + eps)
  664. P->pbs_stat = GLP_INFEAS;
  665. }
  666. }
  667. /* compute value of the objective function */
  668. P->obj_val = P->c0;
  669. for (j = 1; j <= P->n; j++)
  670. { col = P->col[j];
  671. P->obj_val += col->coef * col->prim;
  672. }
  673. /* build vector cB of objective coefficients at basic variables */
  674. for (i = 1; i <= P->m; i++)
  675. work[i] = 0.0;
  676. for (j = 1; j <= P->n; j++)
  677. { col = P->col[j];
  678. if (col->stat == GLP_BS)
  679. work[col->bind] = col->coef;
  680. }
  681. /* compute vector of simplex multipliers pi = inv(B') * cB */
  682. glp_btran(P, work);
  683. /* compute and store reduced costs of non-basic variables d[j] =
  684. c[j] - N'[j] * pi, check dual feasibility */
  685. P->dbs_stat = GLP_FEAS;
  686. for (i = 1; i <= P->m; i++)
  687. { row = P->row[i];
  688. if (row->stat == GLP_BS)
  689. { row->dual = 0.0;
  690. continue;
  691. }
  692. /* N[j] is i-th column of matrix (I|-A) */
  693. row->dual = - work[i];
  694. type = row->type;
  695. temp = (P->dir == GLP_MIN ? + row->dual : - row->dual);
  696. if ((type == GLP_FR || type == GLP_LO) && temp < -1e-5 ||
  697. (type == GLP_FR || type == GLP_UP) && temp > +1e-5)
  698. P->dbs_stat = GLP_INFEAS;
  699. }
  700. for (j = 1; j <= P->n; j++)
  701. { col = P->col[j];
  702. if (col->stat == GLP_BS)
  703. { col->dual = 0.0;
  704. continue;
  705. }
  706. /* N[j] is (m+j)-th column of matrix (I|-A) */
  707. col->dual = col->coef;
  708. for (aij = col->ptr; aij != NULL; aij = aij->c_next)
  709. col->dual += aij->val * work[aij->row->i];
  710. type = col->type;
  711. temp = (P->dir == GLP_MIN ? + col->dual : - col->dual);
  712. if ((type == GLP_FR || type == GLP_LO) && temp < -1e-5 ||
  713. (type == GLP_FR || type == GLP_UP) && temp > +1e-5)
  714. P->dbs_stat = GLP_INFEAS;
  715. }
  716. /* free working array */
  717. xfree(work);
  718. ret = 0;
  719. done: return ret;
  720. }
  721. /***********************************************************************
  722. * NAME
  723. *
  724. * glp_eval_tab_row - compute row of the simplex tableau
  725. *
  726. * SYNOPSIS
  727. *
  728. * int glp_eval_tab_row(glp_prob *lp, int k, int ind[], double val[]);
  729. *
  730. * DESCRIPTION
  731. *
  732. * The routine glp_eval_tab_row computes a row of the current simplex
  733. * tableau for the basic variable, which is specified by the number k:
  734. * if 1 <= k <= m, x[k] is k-th auxiliary variable; if m+1 <= k <= m+n,
  735. * x[k] is (k-m)-th structural variable, where m is number of rows, and
  736. * n is number of columns. The current basis must be available.
  737. *
  738. * The routine stores column indices and numerical values of non-zero
  739. * elements of the computed row using sparse format to the locations
  740. * ind[1], ..., ind[len] and val[1], ..., val[len], respectively, where
  741. * 0 <= len <= n is number of non-zeros returned on exit.
  742. *
  743. * Element indices stored in the array ind have the same sense as the
  744. * index k, i.e. indices 1 to m denote auxiliary variables and indices
  745. * m+1 to m+n denote structural ones (all these variables are obviously
  746. * non-basic by definition).
  747. *
  748. * The computed row shows how the specified basic variable x[k] = xB[i]
  749. * depends on non-basic variables:
  750. *
  751. * xB[i] = alfa[i,1]*xN[1] + alfa[i,2]*xN[2] + ... + alfa[i,n]*xN[n],
  752. *
  753. * where alfa[i,j] are elements of the simplex table row, xN[j] are
  754. * non-basic (auxiliary and structural) variables.
  755. *
  756. * RETURNS
  757. *
  758. * The routine returns number of non-zero elements in the simplex table
  759. * row stored in the arrays ind and val.
  760. *
  761. * BACKGROUND
  762. *
  763. * The system of equality constraints of the LP problem is:
  764. *
  765. * xR = A * xS, (1)
  766. *
  767. * where xR is the vector of auxliary variables, xS is the vector of
  768. * structural variables, A is the matrix of constraint coefficients.
  769. *
  770. * The system (1) can be written in homogenous form as follows:
  771. *
  772. * A~ * x = 0, (2)
  773. *
  774. * where A~ = (I | -A) is the augmented constraint matrix (has m rows
  775. * and m+n columns), x = (xR | xS) is the vector of all (auxiliary and
  776. * structural) variables.
  777. *
  778. * By definition for the current basis we have:
  779. *
  780. * A~ = (B | N), (3)
  781. *
  782. * where B is the basis matrix. Thus, the system (2) can be written as:
  783. *
  784. * B * xB + N * xN = 0. (4)
  785. *
  786. * From (4) it follows that:
  787. *
  788. * xB = A^ * xN, (5)
  789. *
  790. * where the matrix
  791. *
  792. * A^ = - inv(B) * N (6)
  793. *
  794. * is called the simplex table.
  795. *
  796. * It is understood that i-th row of the simplex table is:
  797. *
  798. * e * A^ = - e * inv(B) * N, (7)
  799. *
  800. * where e is a unity vector with e[i] = 1.
  801. *
  802. * To compute i-th row of the simplex table the routine first computes
  803. * i-th row of the inverse:
  804. *
  805. * rho = inv(B') * e, (8)
  806. *
  807. * where B' is a matrix transposed to B, and then computes elements of
  808. * i-th row of the simplex table as scalar products:
  809. *
  810. * alfa[i,j] = - rho * N[j] for all j, (9)
  811. *
  812. * where N[j] is a column of the augmented constraint matrix A~, which
  813. * corresponds to some non-basic auxiliary or structural variable. */
  814. int glp_eval_tab_row(glp_prob *lp, int k, int ind[], double val[])
  815. { int m = lp->m;
  816. int n = lp->n;
  817. int i, t, len, lll, *iii;
  818. double alfa, *rho, *vvv;
  819. if (!(m == 0 || lp->valid))
  820. xerror("glp_eval_tab_row: basis factorization does not exist\n"
  821. );
  822. if (!(1 <= k && k <= m+n))
  823. xerror("glp_eval_tab_row: k = %d; variable number out of range"
  824. , k);
  825. /* determine xB[i] which corresponds to x[k] */
  826. if (k <= m)
  827. i = glp_get_row_bind(lp, k);
  828. else
  829. i = glp_get_col_bind(lp, k-m);
  830. if (i == 0)
  831. xerror("glp_eval_tab_row: k = %d; variable must be basic", k);
  832. xassert(1 <= i && i <= m);
  833. /* allocate working arrays */
  834. rho = xcalloc(1+m, sizeof(double));
  835. iii = xcalloc(1+m, sizeof(int));
  836. vvv = xcalloc(1+m, sizeof(double));
  837. /* compute i-th row of the inverse; see (8) */
  838. for (t = 1; t <= m; t++) rho[t] = 0.0;
  839. rho[i] = 1.0;
  840. glp_btran(lp, rho);
  841. /* compute i-th row of the simplex table */
  842. len = 0;
  843. for (k = 1; k <= m+n; k++)
  844. { if (k <= m)
  845. { /* x[k] is auxiliary variable, so N[k] is a unity column */
  846. if (glp_get_row_stat(lp, k) == GLP_BS) continue;
  847. /* compute alfa[i,j]; see (9) */
  848. alfa = - rho[k];
  849. }
  850. else
  851. { /* x[k] is structural variable, so N[k] is a column of the
  852. original constraint matrix A with negative sign */
  853. if (glp_get_col_stat(lp, k-m) == GLP_BS) continue;
  854. /* compute alfa[i,j]; see (9) */
  855. lll = glp_get_mat_col(lp, k-m, iii, vvv);
  856. alfa = 0.0;
  857. for (t = 1; t <= lll; t++) alfa += rho[iii[t]] * vvv[t];
  858. }
  859. /* store alfa[i,j] */
  860. if (alfa != 0.0) len++, ind[len] = k, val[len] = alfa;
  861. }
  862. xassert(len <= n);
  863. /* free working arrays */
  864. xfree(rho);
  865. xfree(iii);
  866. xfree(vvv);
  867. /* return to the calling program */
  868. return len;
  869. }
  870. /***********************************************************************
  871. * NAME
  872. *
  873. * glp_eval_tab_col - compute column of the simplex tableau
  874. *
  875. * SYNOPSIS
  876. *
  877. * int glp_eval_tab_col(glp_prob *lp, int k, int ind[], double val[]);
  878. *
  879. * DESCRIPTION
  880. *
  881. * The routine glp_eval_tab_col computes a column of the current simplex
  882. * table for the non-basic variable, which is specified by the number k:
  883. * if 1 <= k <= m, x[k] is k-th auxiliary variable; if m+1 <= k <= m+n,
  884. * x[k] is (k-m)-th structural variable, where m is number of rows, and
  885. * n is number of columns. The current basis must be available.
  886. *
  887. * The routine stores row indices and numerical values of non-zero
  888. * elements of the computed column using sparse format to the locations
  889. * ind[1], ..., ind[len] and val[1], ..., val[len] respectively, where
  890. * 0 <= len <= m is number of non-zeros returned on exit.
  891. *
  892. * Element indices stored in the array ind have the same sense as the
  893. * index k, i.e. indices 1 to m denote auxiliary variables and indices
  894. * m+1 to m+n denote structural ones (all these variables are obviously
  895. * basic by the definition).
  896. *
  897. * The computed column shows how basic variables depend on the specified
  898. * non-basic variable x[k] = xN[j]:
  899. *
  900. * xB[1] = ... + alfa[1,j]*xN[j] + ...
  901. * xB[2] = ... + alfa[2,j]*xN[j] + ...
  902. * . . . . . .
  903. * xB[m] = ... + alfa[m,j]*xN[j] + ...
  904. *
  905. * where alfa[i,j] are elements of the simplex table column, xB[i] are
  906. * basic (auxiliary and structural) variables.
  907. *
  908. * RETURNS
  909. *
  910. * The routine returns number of non-zero elements in the simplex table
  911. * column stored in the arrays ind and val.
  912. *
  913. * BACKGROUND
  914. *
  915. * As it was explained in comments to the routine glp_eval_tab_row (see
  916. * above) the simplex table is the following matrix:
  917. *
  918. * A^ = - inv(B) * N. (1)
  919. *
  920. * Therefore j-th column of the simplex table is:
  921. *
  922. * A^ * e = - inv(B) * N * e = - inv(B) * N[j], (2)
  923. *
  924. * where e is a unity vector with e[j] = 1, B is the basis matrix, N[j]
  925. * is a column of the augmented constraint matrix A~, which corresponds
  926. * to the given non-basic auxiliary or structural variable. */
  927. int glp_eval_tab_col(glp_prob *lp, int k, int ind[], double val[])
  928. { int m = lp->m;
  929. int n = lp->n;
  930. int t, len, stat;
  931. double *col;
  932. if (!(m == 0 || lp->valid))
  933. xerror("glp_eval_tab_col: basis factorization does not exist\n"
  934. );
  935. if (!(1 <= k && k <= m+n))
  936. xerror("glp_eval_tab_col: k = %d; variable number out of range"
  937. , k);
  938. if (k <= m)
  939. stat = glp_get_row_stat(lp, k);
  940. else
  941. stat = glp_get_col_stat(lp, k-m);
  942. if (stat == GLP_BS)
  943. xerror("glp_eval_tab_col: k = %d; variable must be non-basic",
  944. k);
  945. /* obtain column N[k] with negative sign */
  946. col = xcalloc(1+m, sizeof(double));
  947. for (t = 1; t <= m; t++) col[t] = 0.0;
  948. if (k <= m)
  949. { /* x[k] is auxiliary variable, so N[k] is a unity column */
  950. col[k] = -1.0;
  951. }
  952. else
  953. { /* x[k] is structural variable, so N[k] is a column of the
  954. original constraint matrix A with negative sign */
  955. len = glp_get_mat_col(lp, k-m, ind, val);
  956. for (t = 1; t <= len; t++) col[ind[t]] = val[t];
  957. }
  958. /* compute column of the simplex table, which corresponds to the
  959. specified non-basic variable x[k] */
  960. glp_ftran(lp, col);
  961. len = 0;
  962. for (t = 1; t <= m; t++)
  963. { if (col[t] != 0.0)
  964. { len++;
  965. ind[len] = glp_get_bhead(lp, t);
  966. val[len] = col[t];
  967. }
  968. }
  969. xfree(col);
  970. /* return to the calling program */
  971. return len;
  972. }
  973. /***********************************************************************
  974. * NAME
  975. *
  976. * glp_transform_row - transform explicitly specified row
  977. *
  978. * SYNOPSIS
  979. *
  980. * int glp_transform_row(glp_prob *P, int len, int ind[], double val[]);
  981. *
  982. * DESCRIPTION
  983. *
  984. * The routine glp_transform_row performs the same operation as the
  985. * routine glp_eval_tab_row with exception that the row to be
  986. * transformed is specified explicitly as a sparse vector.
  987. *
  988. * The explicitly specified row may be thought as a linear form:
  989. *
  990. * x = a[1]*x[m+1] + a[2]*x[m+2] + ... + a[n]*x[m+n], (1)
  991. *
  992. * where x is an auxiliary variable for this row, a[j] are coefficients
  993. * of the linear form, x[m+j] are structural variables.
  994. *
  995. * On entry column indices and numerical values of non-zero elements of
  996. * the row should be stored in locations ind[1], ..., ind[len] and
  997. * val[1], ..., val[len], where len is the number of non-zero elements.
  998. *
  999. * This routine uses the system of equality constraints and the current
  1000. * basis in order to express the auxiliary variable x in (1) through the
  1001. * current non-basic variables (as if the transformed row were added to
  1002. * the problem object and its auxiliary variable were basic), i.e. the
  1003. * resultant row has the form:
  1004. *
  1005. * x = alfa[1]*xN[1] + alfa[2]*xN[2] + ... + alfa[n]*xN[n], (2)
  1006. *
  1007. * where xN[j] are non-basic (auxiliary or structural) variables, n is
  1008. * the number of columns in the LP problem object.
  1009. *
  1010. * On exit the routine stores indices and numerical values of non-zero
  1011. * elements of the resultant row (2) in locations ind[1], ..., ind[len']
  1012. * and val[1], ..., val[len'], where 0 <= len' <= n is the number of
  1013. * non-zero elements in the resultant row returned by the routine. Note
  1014. * that indices (numbers) of non-basic variables stored in the array ind
  1015. * correspond to original ordinal numbers of variables: indices 1 to m
  1016. * mean auxiliary variables and indices m+1 to m+n mean structural ones.
  1017. *
  1018. * RETURNS
  1019. *
  1020. * The routine returns len', which is the number of non-zero elements in
  1021. * the resultant row stored in the arrays ind and val.
  1022. *
  1023. * BACKGROUND
  1024. *
  1025. * The explicitly specified row (1) is transformed in the same way as it
  1026. * were the objective function row.
  1027. *
  1028. * From (1) it follows that:
  1029. *
  1030. * x = aB * xB + aN * xN, (3)
  1031. *
  1032. * where xB is the vector of basic variables, xN is the vector of
  1033. * non-basic variables.
  1034. *
  1035. * The simplex table, which corresponds to the current basis, is:
  1036. *
  1037. * xB = [-inv(B) * N] * xN. (4)
  1038. *
  1039. * Therefore substituting xB from (4) to (3) we have:
  1040. *
  1041. * x = aB * [-inv(B) * N] * xN + aN * xN =
  1042. * (5)
  1043. * = rho * (-N) * xN + aN * xN = alfa * xN,
  1044. *
  1045. * where:
  1046. *
  1047. * rho = inv(B') * aB, (6)
  1048. *
  1049. * and
  1050. *
  1051. * alfa = aN + rho * (-N) (7)
  1052. *
  1053. * is the resultant row computed by the routine. */
  1054. int glp_transform_row(glp_prob *P, int len, int ind[], double val[])
  1055. { int i, j, k, m, n, t, lll, *iii;
  1056. double alfa, *a, *aB, *rho, *vvv;
  1057. if (!glp_bf_exists(P))
  1058. xerror("glp_transform_row: basis factorization does not exist "
  1059. "\n");
  1060. m = glp_get_num_rows(P);
  1061. n = glp_get_num_cols(P);
  1062. /* unpack the row to be transformed to the array a */
  1063. a = xcalloc(1+n, sizeof(double));
  1064. for (j = 1; j <= n; j++) a[j] = 0.0;
  1065. if (!(0 <= len && len <= n))
  1066. xerror("glp_transform_row: len = %d; invalid row length\n",
  1067. len);
  1068. for (t = 1; t <= len; t++)
  1069. { j = ind[t];
  1070. if (!(1 <= j && j <= n))
  1071. xerror("glp_transform_row: ind[%d] = %d; column index out o"
  1072. "f range\n", t, j);
  1073. if (val[t] == 0.0)
  1074. xerror("glp_transform_row: val[%d] = 0; zero coefficient no"
  1075. "t allowed\n", t);
  1076. if (a[j] != 0.0)
  1077. xerror("glp_transform_row: ind[%d] = %d; duplicate column i"
  1078. "ndices not allowed\n", t, j);
  1079. a[j] = val[t];
  1080. }
  1081. /* construct the vector aB */
  1082. aB = xcalloc(1+m, sizeof(double));
  1083. for (i = 1; i <= m; i++)
  1084. { k = glp_get_bhead(P, i);
  1085. /* xB[i] is k-th original variable */
  1086. xassert(1 <= k && k <= m+n);
  1087. aB[i] = (k <= m ? 0.0 : a[k-m]);
  1088. }
  1089. /* solve the system B'*rho = aB to compute the vector rho */
  1090. rho = aB, glp_btran(P, rho);
  1091. /* compute coefficients at non-basic auxiliary variables */
  1092. len = 0;
  1093. for (i = 1; i <= m; i++)
  1094. { if (glp_get_row_stat(P, i) != GLP_BS)
  1095. { alfa = - rho[i];
  1096. if (alfa != 0.0)
  1097. { len++;
  1098. ind[len] = i;
  1099. val[len] = alfa;
  1100. }
  1101. }
  1102. }
  1103. /* compute coefficients at non-basic structural variables */
  1104. iii = xcalloc(1+m, sizeof(int));
  1105. vvv = xcalloc(1+m, sizeof(double));
  1106. for (j = 1; j <= n; j++)
  1107. { if (glp_get_col_stat(P, j) != GLP_BS)
  1108. { alfa = a[j];
  1109. lll = glp_get_mat_col(P, j, iii, vvv);
  1110. for (t = 1; t <= lll; t++) alfa += vvv[t] * rho[iii[t]];
  1111. if (alfa != 0.0)
  1112. { len++;
  1113. ind[len] = m+j;
  1114. val[len] = alfa;
  1115. }
  1116. }
  1117. }
  1118. xassert(len <= n);
  1119. xfree(iii);
  1120. xfree(vvv);
  1121. xfree(aB);
  1122. xfree(a);
  1123. return len;
  1124. }
  1125. /***********************************************************************
  1126. * NAME
  1127. *
  1128. * glp_transform_col - transform explicitly specified column
  1129. *
  1130. * SYNOPSIS
  1131. *
  1132. * int glp_transform_col(glp_prob *P, int len, int ind[], double val[]);
  1133. *
  1134. * DESCRIPTION
  1135. *
  1136. * The routine glp_transform_col performs the same operation as the
  1137. * routine glp_eval_tab_col with exception that the column to be
  1138. * transformed is specified explicitly as a sparse vector.
  1139. *
  1140. * The explicitly specified column may be thought as if it were added
  1141. * to the original system of equality constraints:
  1142. *
  1143. * x[1] = a[1,1]*x[m+1] + ... + a[1,n]*x[m+n] + a[1]*x
  1144. * x[2] = a[2,1]*x[m+1] + ... + a[2,n]*x[m+n] + a[2]*x (1)
  1145. * . . . . . . . . . . . . . . .
  1146. * x[m] = a[m,1]*x[m+1] + ... + a[m,n]*x[m+n] + a[m]*x
  1147. *
  1148. * where x[i] are auxiliary variables, x[m+j] are structural variables,
  1149. * x is a structural variable for the explicitly specified column, a[i]
  1150. * are constraint coefficients for x.
  1151. *
  1152. * On entry row indices and numerical values of non-zero elements of
  1153. * the column should be stored in locations ind[1], ..., ind[len] and
  1154. * val[1], ..., val[len], where len is the number of non-zero elements.
  1155. *
  1156. * This routine uses the system of equality constraints and the current
  1157. * basis in order to express the current basic variables through the
  1158. * structural variable x in (1) (as if the transformed column were added
  1159. * to the problem object and the variable x were non-basic), i.e. the
  1160. * resultant column has the form:
  1161. *
  1162. * xB[1] = ... + alfa[1]*x
  1163. * xB[2] = ... + alfa[2]*x (2)
  1164. * . . . . . .
  1165. * xB[m] = ... + alfa[m]*x
  1166. *
  1167. * where xB are basic (auxiliary and structural) variables, m is the
  1168. * number of rows in the problem object.
  1169. *
  1170. * On exit the routine stores indices and numerical values of non-zero
  1171. * elements of the resultant column (2) in locations ind[1], ...,
  1172. * ind[len'] and val[1], ..., val[len'], where 0 <= len' <= m is the
  1173. * number of non-zero element in the resultant column returned by the
  1174. * routine. Note that indices (numbers) of basic variables stored in
  1175. * the array ind correspond to original ordinal numbers of variables:
  1176. * indices 1 to m mean auxiliary variables and indices m+1 to m+n mean
  1177. * structural ones.
  1178. *
  1179. * RETURNS
  1180. *
  1181. * The routine returns len', which is the number of non-zero elements
  1182. * in the resultant column stored in the arrays ind and val.
  1183. *
  1184. * BACKGROUND
  1185. *
  1186. * The explicitly specified column (1) is transformed in the same way
  1187. * as any other column of the constraint matrix using the formula:
  1188. *
  1189. * alfa = inv(B) * a, (3)
  1190. *
  1191. * where alfa is the resultant column computed by the routine. */
  1192. int glp_transform_col(glp_prob *P, int len, int ind[], double val[])
  1193. { int i, m, t;
  1194. double *a, *alfa;
  1195. if (!glp_bf_exists(P))
  1196. xerror("glp_transform_col: basis factorization does not exist "
  1197. "\n");
  1198. m = glp_get_num_rows(P);
  1199. /* unpack the column to be transformed to the array a */
  1200. a = xcalloc(1+m, sizeof(double));
  1201. for (i = 1; i <= m; i++) a[i] = 0.0;
  1202. if (!(0 <= len && len <= m))
  1203. xerror("glp_transform_col: len = %d; invalid column length\n",
  1204. len);
  1205. for (t = 1; t <= len; t++)
  1206. { i = ind[t];
  1207. if (!(1 <= i && i <= m))
  1208. xerror("glp_transform_col: ind[%d] = %d; row index out of r"
  1209. "ange\n", t, i);
  1210. if (val[t] == 0.0)
  1211. xerror("glp_transform_col: val[%d] = 0; zero coefficient no"
  1212. "t allowed\n", t);
  1213. if (a[i] != 0.0)
  1214. xerror("glp_transform_col: ind[%d] = %d; duplicate row indi"
  1215. "ces not allowed\n", t, i);
  1216. a[i] = val[t];
  1217. }
  1218. /* solve the system B*a = alfa to compute the vector alfa */
  1219. alfa = a, glp_ftran(P, alfa);
  1220. /* store resultant coefficients */
  1221. len = 0;
  1222. for (i = 1; i <= m; i++)
  1223. { if (alfa[i] != 0.0)
  1224. { len++;
  1225. ind[len] = glp_get_bhead(P, i);
  1226. val[len] = alfa[i];
  1227. }
  1228. }
  1229. xfree(a);
  1230. return len;
  1231. }
  1232. /***********************************************************************
  1233. * NAME
  1234. *
  1235. * glp_prim_rtest - perform primal ratio test
  1236. *
  1237. * SYNOPSIS
  1238. *
  1239. * int glp_prim_rtest(glp_prob *P, int len, const int ind[],
  1240. * const double val[], int dir, double eps);
  1241. *
  1242. * DESCRIPTION
  1243. *
  1244. * The routine glp_prim_rtest performs the primal ratio test using an
  1245. * explicitly specified column of the simplex table.
  1246. *
  1247. * The current basic solution associated with the LP problem object
  1248. * must be primal feasible.
  1249. *
  1250. * The explicitly specified column of the simplex table shows how the
  1251. * basic variables xB depend on some non-basic variable x (which is not
  1252. * necessarily presented in the problem object):
  1253. *
  1254. * xB[1] = ... + alfa[1] * x + ...
  1255. * xB[2] = ... + alfa[2] * x + ... (*)
  1256. * . . . . . . . .
  1257. * xB[m] = ... + alfa[m] * x + ...
  1258. *
  1259. * The column (*) is specifed on entry to the routine using the sparse
  1260. * format. Ordinal numbers of basic variables xB[i] should be placed in
  1261. * locations ind[1], ..., ind[len], where ordinal number 1 to m denote
  1262. * auxiliary variables, and ordinal numbers m+1 to m+n denote structural
  1263. * variables. The corresponding non-zero coefficients alfa[i] should be
  1264. * placed in locations val[1], ..., val[len]. The arrays ind and val are
  1265. * not changed on exit.
  1266. *
  1267. * The parameter dir specifies direction in which the variable x changes
  1268. * on entering the basis: +1 means increasing, -1 means decreasing.
  1269. *
  1270. * The parameter eps is an absolute tolerance (small positive number)
  1271. * used by the routine to skip small alfa[j] of the row (*).
  1272. *
  1273. * The routine determines which basic variable (among specified in
  1274. * ind[1], ..., ind[len]) should leave the basis in order to keep primal
  1275. * feasibility.
  1276. *
  1277. * RETURNS
  1278. *
  1279. * The routine glp_prim_rtest returns the index piv in the arrays ind
  1280. * and val corresponding to the pivot element chosen, 1 <= piv <= len.
  1281. * If the adjacent basic solution is primal unbounded and therefore the
  1282. * choice cannot be made, the routine returns zero.
  1283. *
  1284. * COMMENTS
  1285. *
  1286. * If the non-basic variable x is presented in the LP problem object,
  1287. * the column (*) can be computed with the routine glp_eval_tab_col;
  1288. * otherwise it can be computed with the routine glp_transform_col. */
  1289. int glp_prim_rtest(glp_prob *P, int len, const int ind[],
  1290. const double val[], int dir, double eps)
  1291. { int k, m, n, piv, t, type, stat;
  1292. double alfa, big, beta, lb, ub, temp, teta;
  1293. if (glp_get_prim_stat(P) != GLP_FEAS)
  1294. xerror("glp_prim_rtest: basic solution is not primal feasible "
  1295. "\n");
  1296. if (!(dir == +1 || dir == -1))
  1297. xerror("glp_prim_rtest: dir = %d; invalid parameter\n", dir);
  1298. if (!(0.0 < eps && eps < 1.0))
  1299. xerror("glp_prim_rtest: eps = %g; invalid parameter\n", eps);
  1300. m = glp_get_num_rows(P);
  1301. n = glp_get_num_cols(P);
  1302. /* initial settings */
  1303. piv = 0, teta = DBL_MAX, big = 0.0;
  1304. /* walk through the entries of the specified column */
  1305. for (t = 1; t <= len; t++)
  1306. { /* get the ordinal number of basic variable */
  1307. k = ind[t];
  1308. if (!(1 <= k && k <= m+n))
  1309. xerror("glp_prim_rtest: ind[%d] = %d; variable number out o"
  1310. "f range\n", t, k);
  1311. /* determine type, bounds, status and primal value of basic
  1312. variable xB[i] = x[k] in the current basic solution */
  1313. if (k <= m)
  1314. { type = glp_get_row_type(P, k);
  1315. lb = glp_get_row_lb(P, k);
  1316. ub = glp_get_row_ub(P, k);
  1317. stat = glp_get_row_stat(P, k);
  1318. beta = glp_get_row_prim(P, k);
  1319. }
  1320. else
  1321. { type = glp_get_col_type(P, k-m);
  1322. lb = glp_get_col_lb(P, k-m);
  1323. ub = glp_get_col_ub(P, k-m);
  1324. stat = glp_get_col_stat(P, k-m);
  1325. beta = glp_get_col_prim(P, k-m);
  1326. }
  1327. if (stat != GLP_BS)
  1328. xerror("glp_prim_rtest: ind[%d] = %d; non-basic variable no"
  1329. "t allowed\n", t, k);
  1330. /* determine influence coefficient at basic variable xB[i]
  1331. in the explicitly specified column and turn to the case of
  1332. increasing the variable x in order to simplify the program
  1333. logic */
  1334. alfa = (dir > 0 ? + val[t] : - val[t]);
  1335. /* analyze main cases */
  1336. if (type == GLP_FR)
  1337. { /* xB[i] is free variable */
  1338. continue;
  1339. }
  1340. else if (type == GLP_LO)
  1341. lo: { /* xB[i] has an lower bound */
  1342. if (alfa > - eps) continue;
  1343. temp = (lb - beta) / alfa;
  1344. }
  1345. else if (type == GLP_UP)
  1346. up: { /* xB[i] has an upper bound */
  1347. if (alfa < + eps) continue;
  1348. temp = (ub - beta) / alfa;
  1349. }
  1350. else if (type == GLP_DB)
  1351. { /* xB[i] has both lower and upper bounds */
  1352. if (alfa < 0.0) goto lo; else goto up;
  1353. }
  1354. else if (type == GLP_FX)
  1355. { /* xB[i] is fixed variable */
  1356. if (- eps < alfa && alfa < + eps) continue;
  1357. temp = 0.0;
  1358. }
  1359. else
  1360. xassert(type != type);
  1361. /* if the value of the variable xB[i] violates its lower or
  1362. upper bound (slightly, because the current basis is assumed
  1363. to be primal feasible), temp is negative; we can think this
  1364. happens due to round-off errors and the value is exactly on
  1365. the bound; this allows replacing temp by zero */
  1366. if (temp < 0.0) temp = 0.0;
  1367. /* apply the minimal ratio test */
  1368. if (teta > temp || teta == temp && big < fabs(alfa))
  1369. piv = t, teta = temp, big = fabs(alfa);
  1370. }
  1371. /* return index of the pivot element chosen */
  1372. return piv;
  1373. }
  1374. /***********************************************************************
  1375. * NAME
  1376. *
  1377. * glp_dual_rtest - perform dual ratio test
  1378. *
  1379. * SYNOPSIS
  1380. *
  1381. * int glp_dual_rtest(glp_prob *P, int len, const int ind[],
  1382. * const double val[], int dir, double eps);
  1383. *
  1384. * DESCRIPTION
  1385. *
  1386. * The routine glp_dual_rtest performs the dual ratio test using an
  1387. * explicitly specified row of the simplex table.
  1388. *
  1389. * The current basic solution associated with the LP problem object
  1390. * must be dual feasible.
  1391. *
  1392. * The explicitly specified row of the simplex table is a linear form
  1393. * that shows how some basic variable x (which is not necessarily
  1394. * presented in the problem object) depends on non-basic variables xN:
  1395. *
  1396. * x = alfa[1] * xN[1] + alfa[2] * xN[2] + ... + alfa[n] * xN[n]. (*)
  1397. *
  1398. * The row (*) is specified on entry to the routine using the sparse
  1399. * format. Ordinal numbers of non-basic variables xN[j] should be placed
  1400. * in locations ind[1], ..., ind[len], where ordinal numbers 1 to m
  1401. * denote auxiliary variables, and ordinal numbers m+1 to m+n denote
  1402. * structural variables. The corresponding non-zero coefficients alfa[j]
  1403. * should be placed in locations val[1], ..., val[len]. The arrays ind
  1404. * and val are not changed on exit.
  1405. *
  1406. * The parameter dir specifies direction in which the variable x changes
  1407. * on leaving the basis: +1 means that x goes to its lower bound, and -1
  1408. * means that x goes to its upper bound.
  1409. *
  1410. * The parameter eps is an absolute tolerance (small positive number)
  1411. * used by the routine to skip small alfa[j] of the row (*).
  1412. *
  1413. * The routine determines which non-basic variable (among specified in
  1414. * ind[1], ..., ind[len]) should enter the basis in order to keep dual
  1415. * feasibility.
  1416. *
  1417. * RETURNS
  1418. *
  1419. * The routine glp_dual_rtest returns the index piv in the arrays ind
  1420. * and val corresponding to the pivot element chosen, 1 <= piv <= len.
  1421. * If the adjacent basic solution is dual unbounded and therefore the
  1422. * choice cannot be made, the routine returns zero.
  1423. *
  1424. * COMMENTS
  1425. *
  1426. * If the basic variable x is presented in the LP problem object, the
  1427. * row (*) can be computed with the routine glp_eval_tab_row; otherwise
  1428. * it can be computed with the routine glp_transform_row. */
  1429. int glp_dual_rtest(glp_prob *P, int len, const int ind[],
  1430. const double val[], int dir, double eps)
  1431. { int k, m, n, piv, t, stat;
  1432. double alfa, big, cost, obj, temp, teta;
  1433. if (glp_get_dual_stat(P) != GLP_FEAS)
  1434. xerror("glp_dual_rtest: basic solution is not dual feasible\n")
  1435. ;
  1436. if (!(dir == +1 || dir == -1))
  1437. xerror("glp_dual_rtest: dir = %d; invalid parameter\n", dir);
  1438. if (!(0.0 < eps && eps < 1.0))
  1439. xerror("glp_dual_rtest: eps = %g; invalid parameter\n", eps);
  1440. m = glp_get_num_rows(P);
  1441. n = glp_get_num_cols(P);
  1442. /* take into account optimization direction */
  1443. obj = (glp_get_obj_dir(P) == GLP_MIN ? +1.0 : -1.0);
  1444. /* initial settings */
  1445. piv = 0, teta = DBL_MAX, big = 0.0;
  1446. /* walk through the entries of the specified row */
  1447. for (t = 1; t <= len; t++)
  1448. { /* get ordinal number of non-basic variable */
  1449. k = ind[t];
  1450. if (!(1 <= k && k <= m+n))
  1451. xerror("glp_dual_rtest: ind[%d] = %d; variable number out o"
  1452. "f range\n", t, k);
  1453. /* determine status and reduced cost of non-basic variable
  1454. x[k] = xN[j] in the current basic solution */
  1455. if (k <= m)
  1456. { stat = glp_get_row_stat(P, k);
  1457. cost = glp_get_row_dual(P, k);
  1458. }
  1459. else
  1460. { stat = glp_get_col_stat(P, k-m);
  1461. cost = glp_get_col_dual(P, k-m);
  1462. }
  1463. if (stat == GLP_BS)
  1464. xerror("glp_dual_rtest: ind[%d] = %d; basic variable not al"
  1465. "lowed\n", t, k);
  1466. /* determine influence coefficient at non-basic variable xN[j]
  1467. in the explicitly specified row and turn to the case of
  1468. increasing the variable x in order to simplify the program
  1469. logic */
  1470. alfa = (dir > 0 ? + val[t] : - val[t]);
  1471. /* analyze main cases */
  1472. if (stat == GLP_NL)
  1473. { /* xN[j] is on its lower bound */
  1474. if (alfa < + eps) continue;
  1475. temp = (obj * cost) / alfa;
  1476. }
  1477. else if (stat == GLP_NU)
  1478. { /* xN[j] is on its upper bound */
  1479. if (alfa > - eps) continue;
  1480. temp = (obj * cost) / alfa;
  1481. }
  1482. else if (stat == GLP_NF)
  1483. { /* xN[j] is non-basic free variable */
  1484. if (- eps < alfa && alfa < + eps) continue;
  1485. temp = 0.0;
  1486. }
  1487. else if (stat == GLP_NS)
  1488. { /* xN[j] is non-basic fixed variable */
  1489. continue;
  1490. }
  1491. else
  1492. xassert(stat != stat);
  1493. /* if the reduced cost of the variable xN[j] violates its zero
  1494. bound (slightly, because the current basis is assumed to be
  1495. dual feasible), temp is negative; we can think this happens
  1496. due to round-off errors and the reduced cost is exact zero;
  1497. this allows replacing temp by zero */
  1498. if (temp < 0.0) temp = 0.0;
  1499. /* apply the minimal ratio test */
  1500. if (teta > temp || teta == temp && big < fabs(alfa))
  1501. piv = t, teta = temp, big = fabs(alfa);
  1502. }
  1503. /* return index of the pivot element chosen */
  1504. return piv;
  1505. }
  1506. /***********************************************************************
  1507. * NAME
  1508. *
  1509. * glp_analyze_row - simulate one iteration of dual simplex method
  1510. *
  1511. * SYNOPSIS
  1512. *
  1513. * int glp_analyze_row(glp_prob *P, int len, const int ind[],
  1514. * const double val[], int type, double rhs, double eps, int *piv,
  1515. * double *x, double *dx, double *y, double *dy, double *dz);
  1516. *
  1517. * DESCRIPTION
  1518. *
  1519. * Let the current basis be optimal or dual feasible, and there be
  1520. * specified a row (constraint), which is violated by the current basic
  1521. * solution. The routine glp_analyze_row simulates one iteration of the
  1522. * dual simplex method to determine some information on the adjacent
  1523. * basis (see below), where the specified row becomes active constraint
  1524. * (i.e. its auxiliary variable becomes non-basic).
  1525. *
  1526. * The current basic solution associated with the problem object passed
  1527. * to the routine must be dual feasible, and its primal components must
  1528. * be defined.
  1529. *
  1530. * The row to be analyzed must be previously transformed either with
  1531. * the routine glp_eval_tab_row (if the row is in the problem object)
  1532. * or with the routine glp_transform_row (if the row is external, i.e.
  1533. * not in the problem object). This is needed to express the row only
  1534. * through (auxiliary and structural) variables, which are non-basic in
  1535. * the current basis:
  1536. *
  1537. * y = alfa[1] * xN[1] + alfa[2] * xN[2] + ... + alfa[n] * xN[n],
  1538. *
  1539. * where y is an auxiliary variable of the row, alfa[j] is an influence
  1540. * coefficient, xN[j] is a non-basic variable.
  1541. *
  1542. * The row is passed to the routine in sparse format. Ordinal numbers
  1543. * of non-basic variables are stored in locations ind[1], ..., ind[len],
  1544. * where numbers 1 to m denote auxiliary variables while numbers m+1 to
  1545. * m+n denote structural variables. Corresponding non-zero coefficients
  1546. * alfa[j] are stored in locations val[1], ..., val[len]. The arrays
  1547. * ind and val are ot changed on exit.
  1548. *
  1549. * The parameters type and rhs specify the row type and its right-hand
  1550. * side as follows:
  1551. *
  1552. * type = GLP_LO: y = sum alfa[j] * xN[j] >= rhs
  1553. *
  1554. * type = GLP_UP: y = sum alfa[j] * xN[j] <= rhs
  1555. *
  1556. * The parameter eps is an absolute tolerance (small positive number)
  1557. * used by the routine to skip small coefficients alfa[j] on performing
  1558. * the dual ratio test.
  1559. *
  1560. * If the operation was successful, the routine stores the following
  1561. * information to corresponding location (if some parameter is NULL,
  1562. * its value is not stored):
  1563. *
  1564. * piv index in the array ind and val, 1 <= piv <= len, determining
  1565. * the non-basic variable, which would enter the adjacent basis;
  1566. *
  1567. * x value of the non-basic variable in the current basis;
  1568. *
  1569. * dx difference between values of the non-basic variable in the
  1570. * adjacent and current bases, dx = x.new - x.old;
  1571. *
  1572. * y value of the row (i.e. of its auxiliary variable) in the
  1573. * current basis;
  1574. *
  1575. * dy difference between values of the row in the adjacent and
  1576. * current bases, dy = y.new - y.old;
  1577. *
  1578. * dz difference between values of the objective function in the
  1579. * adjacent and current bases, dz = z.new - z.old. Note that in
  1580. * case of minimization dz >= 0, and in case of maximization
  1581. * dz <= 0, i.e. in the adjacent basis the objective function
  1582. * always gets worse (degrades). */
  1583. int _glp_analyze_row(glp_prob *P, int len, const int ind[],
  1584. const double val[], int type, double rhs, double eps, int *_piv,
  1585. double *_x, double *_dx, double *_y, double *_dy, double *_dz)
  1586. { int t, k, dir, piv, ret = 0;
  1587. double x, dx, y, dy, dz;
  1588. if (P->pbs_stat == GLP_UNDEF)
  1589. xerror("glp_analyze_row: primal basic solution components are "
  1590. "undefined\n");
  1591. if (P->dbs_stat != GLP_FEAS)
  1592. xerror("glp_analyze_row: basic solution is not dual feasible\n"
  1593. );
  1594. /* compute the row value y = sum alfa[j] * xN[j] in the current
  1595. basis */
  1596. if (!(0 <= len && len <= P->n))
  1597. xerror("glp_analyze_row: len = %d; invalid row length\n", len);
  1598. y = 0.0;
  1599. for (t = 1; t <= len; t++)
  1600. { /* determine value of x[k] = xN[j] in the current basis */
  1601. k = ind[t];
  1602. if (!(1 <= k && k <= P->m+P->n))
  1603. xerror("glp_analyze_row: ind[%d] = %d; row/column index out"
  1604. " of range\n", t, k);
  1605. if (k <= P->m)
  1606. { /* x[k] is auxiliary variable */
  1607. if (P->row[k]->stat == GLP_BS)
  1608. xerror("glp_analyze_row: ind[%d] = %d; basic auxiliary v"
  1609. "ariable is not allowed\n", t, k);
  1610. x = P->row[k]->prim;
  1611. }
  1612. else
  1613. { /* x[k] is structural variable */
  1614. if (P->col[k-P->m]->stat == GLP_BS)
  1615. xerror("glp_analyze_row: ind[%d] = %d; basic structural "
  1616. "variable is not allowed\n", t, k);
  1617. x = P->col[k-P->m]->prim;
  1618. }
  1619. y += val[t] * x;
  1620. }
  1621. /* check if the row is primal infeasible in the current basis,
  1622. i.e. the constraint is violated at the current point */
  1623. if (type == GLP_LO)
  1624. { if (y >= rhs)
  1625. { /* the constraint is not violated */
  1626. ret = 1;
  1627. goto done;
  1628. }
  1629. /* in the adjacent basis y goes to its lower bound */
  1630. dir = +1;
  1631. }
  1632. else if (type == GLP_UP)
  1633. { if (y <= rhs)
  1634. { /* the constraint is not violated */
  1635. ret = 1;
  1636. goto done;
  1637. }
  1638. /* in the adjacent basis y goes to its upper bound */
  1639. dir = -1;
  1640. }
  1641. else
  1642. xerror("glp_analyze_row: type = %d; invalid parameter\n",
  1643. type);
  1644. /* compute dy = y.new - y.old */
  1645. dy = rhs - y;
  1646. /* perform dual ratio test to determine which non-basic variable
  1647. should enter the adjacent basis to keep it dual feasible */
  1648. piv = glp_dual_rtest(P, len, ind, val, dir, eps);
  1649. if (piv == 0)
  1650. { /* no dual feasible adjacent basis exists */
  1651. ret = 2;
  1652. goto done;
  1653. }
  1654. /* non-basic variable x[k] = xN[j] should enter the basis */
  1655. k = ind[piv];
  1656. xassert(1 <= k && k <= P->m+P->n);
  1657. /* determine its value in the current basis */
  1658. if (k <= P->m)
  1659. x = P->row[k]->prim;
  1660. else
  1661. x = P->col[k-P->m]->prim;
  1662. /* compute dx = x.new - x.old = dy / alfa[j] */
  1663. xassert(val[piv] != 0.0);
  1664. dx = dy / val[piv];
  1665. /* compute dz = z.new - z.old = d[j] * dx, where d[j] is reduced
  1666. cost of xN[j] in the current basis */
  1667. if (k <= P->m)
  1668. dz = P->row[k]->dual * dx;
  1669. else
  1670. dz = P->col[k-P->m]->dual * dx;
  1671. /* store the analysis results */
  1672. if (_piv != NULL) *_piv = piv;
  1673. if (_x != NULL) *_x = x;
  1674. if (_dx != NULL) *_dx = dx;
  1675. if (_y != NULL) *_y = y;
  1676. if (_dy != NULL) *_dy = dy;
  1677. if (_dz != NULL) *_dz = dz;
  1678. done: return ret;
  1679. }
  1680. #if 0
  1681. int main(void)
  1682. { /* example program for the routine glp_analyze_row */
  1683. glp_prob *P;
  1684. glp_smcp parm;
  1685. int i, k, len, piv, ret, ind[1+100];
  1686. double rhs, x, dx, y, dy, dz, val[1+100];
  1687. P = glp_create_prob();
  1688. /* read plan.mps (see glpk/examples) */
  1689. ret = glp_read_mps(P, GLP_MPS_DECK, NULL, "plan.mps");
  1690. glp_assert(ret == 0);
  1691. /* and solve it to optimality */
  1692. ret = glp_simplex(P, NULL);
  1693. glp_assert(ret == 0);
  1694. glp_assert(glp_get_status(P) == GLP_OPT);
  1695. /* the optimal objective value is 296.217 */
  1696. /* we would like to know what happens if we would add a new row
  1697. (constraint) to plan.mps:
  1698. .01 * bin1 + .01 * bin2 + .02 * bin4 + .02 * bin5 <= 12 */
  1699. /* first, we specify this new row */
  1700. glp_create_index(P);
  1701. len = 0;
  1702. ind[++len] = glp_find_col(P, "BIN1"), val[len] = .01;
  1703. ind[++len] = glp_find_col(P, "BIN2"), val[len] = .01;
  1704. ind[++len] = glp_find_col(P, "BIN4"), val[len] = .02;
  1705. ind[++len] = glp_find_col(P, "BIN5"), val[len] = .02;
  1706. rhs = 12;
  1707. /* then we can compute value of the row (i.e. of its auxiliary
  1708. variable) in the current basis to see if the constraint is
  1709. violated */
  1710. y = 0.0;
  1711. for (k = 1; k <= len; k++)
  1712. y += val[k] * glp_get_col_prim(P, ind[k]);
  1713. glp_printf("y = %g\n", y);
  1714. /* this prints y = 15.1372, so the constraint is violated, since
  1715. we require that y <= rhs = 12 */
  1716. /* now we transform the row to express it only through non-basic
  1717. (auxiliary and artificial) variables */
  1718. len = glp_transform_row(P, len, ind, val);
  1719. /* finally, we simulate one step of the dual simplex method to
  1720. obtain necessary information for the adjacent basis */
  1721. ret = _glp_analyze_row(P, len, ind, val, GLP_UP, rhs, 1e-9, &piv,
  1722. &x, &dx, &y, &dy, &dz);
  1723. glp_assert(ret == 0);
  1724. glp_printf("k = %d, x = %g; dx = %g; y = %g; dy = %g; dz = %g\n",
  1725. ind[piv], x, dx, y, dy, dz);
  1726. /* this prints dz = 5.64418 and means that in the adjacent basis
  1727. the objective function would be 296.217 + 5.64418 = 301.861 */
  1728. /* now we actually include the row into the problem object; note
  1729. that the arrays ind and val are clobbered, so we need to build
  1730. them once again */
  1731. len = 0;
  1732. ind[++len] = glp_find_col(P, "BIN1"), val[len] = .01;
  1733. ind[++len] = glp_find_col(P, "BIN2"), val[len] = .01;
  1734. ind[++len] = glp_find_col(P, "BIN4"), val[len] = .02;
  1735. ind[++len] = glp_find_col(P, "BIN5"), val[len] = .02;
  1736. rhs = 12;
  1737. i = glp_add_rows(P, 1);
  1738. glp_set_row_bnds(P, i, GLP_UP, 0, rhs);
  1739. glp_set_mat_row(P, i, len, ind, val);
  1740. /* and perform one dual simplex iteration */
  1741. glp_init_smcp(&parm);
  1742. parm.meth = GLP_DUAL;
  1743. parm.it_lim = 1;
  1744. glp_simplex(P, &parm);
  1745. /* the current objective value is 301.861 */
  1746. return 0;
  1747. }
  1748. #endif
  1749. /***********************************************************************
  1750. * NAME
  1751. *
  1752. * glp_analyze_bound - analyze active bound of non-basic variable
  1753. *
  1754. * SYNOPSIS
  1755. *
  1756. * void glp_analyze_bound(glp_prob *P, int k, double *limit1, int *var1,
  1757. * double *limit2, int *var2);
  1758. *
  1759. * DESCRIPTION
  1760. *
  1761. * The routine glp_analyze_bound analyzes the effect of varying the
  1762. * active bound of specified non-basic variable.
  1763. *
  1764. * The non-basic variable is specified by the parameter k, where
  1765. * 1 <= k <= m means auxiliary variable of corresponding row while
  1766. * m+1 <= k <= m+n means structural variable (column).
  1767. *
  1768. * Note that the current basic solution must be optimal, and the basis
  1769. * factorization must exist.
  1770. *
  1771. * Results of the analysis have the following meaning.
  1772. *
  1773. * value1 is the minimal value of the active bound, at which the basis
  1774. * still remains primal feasible and thus optimal. -DBL_MAX means that
  1775. * the active bound has no lower limit.
  1776. *
  1777. * var1 is the ordinal number of an auxiliary (1 to m) or structural
  1778. * (m+1 to n) basic variable, which reaches its bound first and thereby
  1779. * limits further decreasing the active bound being analyzed.
  1780. * if value1 = -DBL_MAX, var1 is set to 0.
  1781. *
  1782. * value2 is the maximal value of the active bound, at which the basis
  1783. * still remains primal feasible and thus optimal. +DBL_MAX means that
  1784. * the active bound has no upper limit.
  1785. *
  1786. * var2 is the ordinal number of an auxiliary (1 to m) or structural
  1787. * (m+1 to n) basic variable, which reaches its bound first and thereby
  1788. * limits further increasing the active bound being analyzed.
  1789. * if value2 = +DBL_MAX, var2 is set to 0. */
  1790. void glp_analyze_bound(glp_prob *P, int k, double *value1, int *var1,
  1791. double *value2, int *var2)
  1792. { GLPROW *row;
  1793. GLPCOL *col;
  1794. int m, n, stat, kase, p, len, piv, *ind;
  1795. double x, new_x, ll, uu, xx, delta, *val;
  1796. /* sanity checks */
  1797. if (P == NULL || P->magic != GLP_PROB_MAGIC)
  1798. xerror("glp_analyze_bound: P = %p; invalid problem object\n",
  1799. P);
  1800. m = P->m, n = P->n;
  1801. if (!(P->pbs_stat == GLP_FEAS && P->dbs_stat == GLP_FEAS))
  1802. xerror("glp_analyze_bound: optimal basic solution required\n");
  1803. if (!(m == 0 || P->valid))
  1804. xerror("glp_analyze_bound: basis factorization required\n");
  1805. if (!(1 <= k && k <= m+n))
  1806. xerror("glp_analyze_bound: k = %d; variable number out of rang"
  1807. "e\n", k);
  1808. /* retrieve information about the specified non-basic variable
  1809. x[k] whose active bound is to be analyzed */
  1810. if (k <= m)
  1811. { row = P->row[k];
  1812. stat = row->stat;
  1813. x = row->prim;
  1814. }
  1815. else
  1816. { col = P->col[k-m];
  1817. stat = col->stat;
  1818. x = col->prim;
  1819. }
  1820. if (stat == GLP_BS)
  1821. xerror("glp_analyze_bound: k = %d; basic variable not allowed "
  1822. "\n", k);
  1823. /* allocate working arrays */
  1824. ind = xcalloc(1+m, sizeof(int));
  1825. val = xcalloc(1+m, sizeof(double));
  1826. /* compute column of the simplex table corresponding to the
  1827. non-basic variable x[k] */
  1828. len = glp_eval_tab_col(P, k, ind, val);
  1829. xassert(0 <= len && len <= m);
  1830. /* perform analysis */
  1831. for (kase = -1; kase <= +1; kase += 2)
  1832. { /* kase < 0 means active bound of x[k] is decreasing;
  1833. kase > 0 means active bound of x[k] is increasing */
  1834. /* use the primal ratio test to determine some basic variable
  1835. x[p] which reaches its bound first */
  1836. piv = glp_prim_rtest(P, len, ind, val, kase, 1e-9);
  1837. if (piv == 0)
  1838. { /* nothing limits changing the active bound of x[k] */
  1839. p = 0;
  1840. new_x = (kase < 0 ? -DBL_MAX : +DBL_MAX);
  1841. goto store;
  1842. }
  1843. /* basic variable x[p] limits changing the active bound of
  1844. x[k]; determine its value in the current basis */
  1845. xassert(1 <= piv && piv <= len);
  1846. p = ind[piv];
  1847. if (p <= m)
  1848. { row = P->row[p];
  1849. ll = glp_get_row_lb(P, row->i);
  1850. uu = glp_get_row_ub(P, row->i);
  1851. stat = row->stat;
  1852. xx = row->prim;
  1853. }
  1854. else
  1855. { col = P->col[p-m];
  1856. ll = glp_get_col_lb(P, col->j);
  1857. uu = glp_get_col_ub(P, col->j);
  1858. stat = col->stat;
  1859. xx = col->prim;
  1860. }
  1861. xassert(stat == GLP_BS);
  1862. /* determine delta x[p] = bound of x[p] - value of x[p] */
  1863. if (kase < 0 && val[piv] > 0.0 ||
  1864. kase > 0 && val[piv] < 0.0)
  1865. { /* delta x[p] < 0, so x[p] goes toward its lower bound */
  1866. xassert(ll != -DBL_MAX);
  1867. delta = ll - xx;
  1868. }
  1869. else
  1870. { /* delta x[p] > 0, so x[p] goes toward its upper bound */
  1871. xassert(uu != +DBL_MAX);
  1872. delta = uu - xx;
  1873. }
  1874. /* delta x[p] = alfa[p,k] * delta x[k], so new x[k] = x[k] +
  1875. delta x[k] = x[k] + delta x[p] / alfa[p,k] is the value of
  1876. x[k] in the adjacent basis */
  1877. xassert(val[piv] != 0.0);
  1878. new_x = x + delta / val[piv];
  1879. store: /* store analysis results */
  1880. if (kase < 0)
  1881. { if (value1 != NULL) *value1 = new_x;
  1882. if (var1 != NULL) *var1 = p;
  1883. }
  1884. else
  1885. { if (value2 != NULL) *value2 = new_x;
  1886. if (var2 != NULL) *var2 = p;
  1887. }
  1888. }
  1889. /* free working arrays */
  1890. xfree(ind);
  1891. xfree(val);
  1892. return;
  1893. }
  1894. /***********************************************************************
  1895. * NAME
  1896. *
  1897. * glp_analyze_coef - analyze objective coefficient at basic variable
  1898. *
  1899. * SYNOPSIS
  1900. *
  1901. * void glp_analyze_coef(glp_prob *P, int k, double *coef1, int *var1,
  1902. * double *value1, double *coef2, int *var2, double *value2);
  1903. *
  1904. * DESCRIPTION
  1905. *
  1906. * The routine glp_analyze_coef analyzes the effect of varying the
  1907. * objective coefficient at specified basic variable.
  1908. *
  1909. * The basic variable is specified by the parameter k, where
  1910. * 1 <= k <= m means auxiliary variable of corresponding row while
  1911. * m+1 <= k <= m+n means structural variable (column).
  1912. *
  1913. * Note that the current basic solution must be optimal, and the basis
  1914. * factorization must exist.
  1915. *
  1916. * Results of the analysis have the following meaning.
  1917. *
  1918. * coef1 is the minimal value of the objective coefficient, at which
  1919. * the basis still remains dual feasible and thus optimal. -DBL_MAX
  1920. * means that the objective coefficient has no lower limit.
  1921. *
  1922. * var1 is the ordinal number of an auxiliary (1 to m) or structural
  1923. * (m+1 to n) non-basic variable, whose reduced cost reaches its zero
  1924. * bound first and thereby limits further decreasing the objective
  1925. * coefficient being analyzed. If coef1 = -DBL_MAX, var1 is set to 0.
  1926. *
  1927. * value1 is value of the basic variable being analyzed in an adjacent
  1928. * basis, which is defined as follows. Let the objective coefficient
  1929. * reaches its minimal value (coef1) and continues decreasing. Then the
  1930. * reduced cost of the limiting non-basic variable (var1) becomes dual
  1931. * infeasible and the current basis becomes non-optimal that forces the
  1932. * limiting non-basic variable to enter the basis replacing there some
  1933. * basic variable that leaves the basis to keep primal feasibility.
  1934. * Should note that on determining the adjacent basis current bounds
  1935. * of the basic variable being analyzed are ignored as if it were free
  1936. * (unbounded) variable, so it cannot leave the basis. It may happen
  1937. * that no dual feasible adjacent basis exists, in which case value1 is
  1938. * set to -DBL_MAX or +DBL_MAX.
  1939. *
  1940. * coef2 is the maximal value of the objective coefficient, at which
  1941. * the basis still remains dual feasible and thus optimal. +DBL_MAX
  1942. * means that the objective coefficient has no upper limit.
  1943. *
  1944. * var2 is the ordinal number of an auxiliary (1 to m) or structural
  1945. * (m+1 to n) non-basic variable, whose reduced cost reaches its zero
  1946. * bound first and thereby limits further increasing the objective
  1947. * coefficient being analyzed. If coef2 = +DBL_MAX, var2 is set to 0.
  1948. *
  1949. * value2 is value of the basic variable being analyzed in an adjacent
  1950. * basis, which is defined exactly in the same way as value1 above with
  1951. * exception that now the objective coefficient is increasing. */
  1952. void glp_analyze_coef(glp_prob *P, int k, double *coef1, int *var1,
  1953. double *value1, double *coef2, int *var2, double *value2)
  1954. { GLPROW *row; GLPCOL *col;
  1955. int m, n, type, stat, kase, p, q, dir, clen, cpiv, rlen, rpiv,
  1956. *cind, *rind;
  1957. double lb, ub, coef, x, lim_coef, new_x, d, delta, ll, uu, xx,
  1958. *rval, *cval;
  1959. /* sanity checks */
  1960. if (P == NULL || P->magic != GLP_PROB_MAGIC)
  1961. xerror("glp_analyze_coef: P = %p; invalid problem object\n",
  1962. P);
  1963. m = P->m, n = P->n;
  1964. if (!(P->pbs_stat == GLP_FEAS && P->dbs_stat == GLP_FEAS))
  1965. xerror("glp_analyze_coef: optimal basic solution required\n");
  1966. if (!(m == 0 || P->valid))
  1967. xerror("glp_analyze_coef: basis factorization required\n");
  1968. if (!(1 <= k && k <= m+n))
  1969. xerror("glp_analyze_coef: k = %d; variable number out of range"
  1970. "\n", k);
  1971. /* retrieve information about the specified basic variable x[k]
  1972. whose objective coefficient c[k] is to be analyzed */
  1973. if (k <= m)
  1974. { row = P->row[k];
  1975. type = row->type;
  1976. lb = row->lb;
  1977. ub = row->ub;
  1978. coef = 0.0;
  1979. stat = row->stat;
  1980. x = row->prim;
  1981. }
  1982. else
  1983. { col = P->col[k-m];
  1984. type = col->type;
  1985. lb = col->lb;
  1986. ub = col->ub;
  1987. coef = col->coef;
  1988. stat = col->stat;
  1989. x = col->prim;
  1990. }
  1991. if (stat != GLP_BS)
  1992. xerror("glp_analyze_coef: k = %d; non-basic variable not allow"
  1993. "ed\n", k);
  1994. /* allocate working arrays */
  1995. cind = xcalloc(1+m, sizeof(int));
  1996. cval = xcalloc(1+m, sizeof(double));
  1997. rind = xcalloc(1+n, sizeof(int));
  1998. rval = xcalloc(1+n, sizeof(double));
  1999. /* compute row of the simplex table corresponding to the basic
  2000. variable x[k] */
  2001. rlen = glp_eval_tab_row(P, k, rind, rval);
  2002. xassert(0 <= rlen && rlen <= n);
  2003. /* perform analysis */
  2004. for (kase = -1; kase <= +1; kase += 2)
  2005. { /* kase < 0 means objective coefficient c[k] is decreasing;
  2006. kase > 0 means objective coefficient c[k] is increasing */
  2007. /* note that decreasing c[k] is equivalent to increasing dual
  2008. variable lambda[k] and vice versa; we need to correctly set
  2009. the dir flag as required by the routine glp_dual_rtest */
  2010. if (P->dir == GLP_MIN)
  2011. dir = - kase;
  2012. else if (P->dir == GLP_MAX)
  2013. dir = + kase;
  2014. else
  2015. xassert(P != P);
  2016. /* use the dual ratio test to determine non-basic variable
  2017. x[q] whose reduced cost d[q] reaches zero bound first */
  2018. rpiv = glp_dual_rtest(P, rlen, rind, rval, dir, 1e-9);
  2019. if (rpiv == 0)
  2020. { /* nothing limits changing c[k] */
  2021. lim_coef = (kase < 0 ? -DBL_MAX : +DBL_MAX);
  2022. q = 0;
  2023. /* x[k] keeps its current value */
  2024. new_x = x;
  2025. goto store;
  2026. }
  2027. /* non-basic variable x[q] limits changing coefficient c[k];
  2028. determine its status and reduced cost d[k] in the current
  2029. basis */
  2030. xassert(1 <= rpiv && rpiv <= rlen);
  2031. q = rind[rpiv];
  2032. xassert(1 <= q && q <= m+n);
  2033. if (q <= m)
  2034. { row = P->row[q];
  2035. stat = row->stat;
  2036. d = row->dual;
  2037. }
  2038. else
  2039. { col = P->col[q-m];
  2040. stat = col->stat;
  2041. d = col->dual;
  2042. }
  2043. /* note that delta d[q] = new d[q] - d[q] = - d[q], because
  2044. new d[q] = 0; delta d[q] = alfa[k,q] * delta c[k], so
  2045. delta c[k] = delta d[q] / alfa[k,q] = - d[q] / alfa[k,q] */
  2046. xassert(rval[rpiv] != 0.0);
  2047. delta = - d / rval[rpiv];
  2048. /* compute new c[k] = c[k] + delta c[k], which is the limiting
  2049. value of the objective coefficient c[k] */
  2050. lim_coef = coef + delta;
  2051. /* let c[k] continue decreasing/increasing that makes d[q]
  2052. dual infeasible and forces x[q] to enter the basis;
  2053. to perform the primal ratio test we need to know in which
  2054. direction x[q] changes on entering the basis; we determine
  2055. that analyzing the sign of delta d[q] (see above), since
  2056. d[q] may be close to zero having wrong sign */
  2057. /* let, for simplicity, the problem is minimization */
  2058. if (kase < 0 && rval[rpiv] > 0.0 ||
  2059. kase > 0 && rval[rpiv] < 0.0)
  2060. { /* delta d[q] < 0, so d[q] being non-negative will become
  2061. negative, so x[q] will increase */
  2062. dir = +1;
  2063. }
  2064. else
  2065. { /* delta d[q] > 0, so d[q] being non-positive will become
  2066. positive, so x[q] will decrease */
  2067. dir = -1;
  2068. }
  2069. /* if the problem is maximization, correct the direction */
  2070. if (P->dir == GLP_MAX) dir = - dir;
  2071. /* check that we didn't make a silly mistake */
  2072. if (dir > 0)
  2073. xassert(stat == GLP_NL || stat == GLP_NF);
  2074. else
  2075. xassert(stat == GLP_NU || stat == GLP_NF);
  2076. /* compute column of the simplex table corresponding to the
  2077. non-basic variable x[q] */
  2078. clen = glp_eval_tab_col(P, q, cind, cval);
  2079. /* make x[k] temporarily free (unbounded) */
  2080. if (k <= m)
  2081. { row = P->row[k];
  2082. row->type = GLP_FR;
  2083. row->lb = row->ub = 0.0;
  2084. }
  2085. else
  2086. { col = P->col[k-m];
  2087. col->type = GLP_FR;
  2088. col->lb = col->ub = 0.0;
  2089. }
  2090. /* use the primal ratio test to determine some basic variable
  2091. which leaves the basis */
  2092. cpiv = glp_prim_rtest(P, clen, cind, cval, dir, 1e-9);
  2093. /* restore original bounds of the basic variable x[k] */
  2094. if (k <= m)
  2095. { row = P->row[k];
  2096. row->type = type;
  2097. row->lb = lb, row->ub = ub;
  2098. }
  2099. else
  2100. { col = P->col[k-m];
  2101. col->type = type;
  2102. col->lb = lb, col->ub = ub;
  2103. }
  2104. if (cpiv == 0)
  2105. { /* non-basic variable x[q] can change unlimitedly */
  2106. if (dir < 0 && rval[rpiv] > 0.0 ||
  2107. dir > 0 && rval[rpiv] < 0.0)
  2108. { /* delta x[k] = alfa[k,q] * delta x[q] < 0 */
  2109. new_x = -DBL_MAX;
  2110. }
  2111. else
  2112. { /* delta x[k] = alfa[k,q] * delta x[q] > 0 */
  2113. new_x = +DBL_MAX;
  2114. }
  2115. goto store;
  2116. }
  2117. /* some basic variable x[p] limits changing non-basic variable
  2118. x[q] in the adjacent basis */
  2119. xassert(1 <= cpiv && cpiv <= clen);
  2120. p = cind[cpiv];
  2121. xassert(1 <= p && p <= m+n);
  2122. xassert(p != k);
  2123. if (p <= m)
  2124. { row = P->row[p];
  2125. xassert(row->stat == GLP_BS);
  2126. ll = glp_get_row_lb(P, row->i);
  2127. uu = glp_get_row_ub(P, row->i);
  2128. xx = row->prim;
  2129. }
  2130. else
  2131. { col = P->col[p-m];
  2132. xassert(col->stat == GLP_BS);
  2133. ll = glp_get_col_lb(P, col->j);
  2134. uu = glp_get_col_ub(P, col->j);
  2135. xx = col->prim;
  2136. }
  2137. /* determine delta x[p] = new x[p] - x[p] */
  2138. if (dir < 0 && cval[cpiv] > 0.0 ||
  2139. dir > 0 && cval[cpiv] < 0.0)
  2140. { /* delta x[p] < 0, so x[p] goes toward its lower bound */
  2141. xassert(ll != -DBL_MAX);
  2142. delta = ll - xx;
  2143. }
  2144. else
  2145. { /* delta x[p] > 0, so x[p] goes toward its upper bound */
  2146. xassert(uu != +DBL_MAX);
  2147. delta = uu - xx;
  2148. }
  2149. /* compute new x[k] = x[k] + alfa[k,q] * delta x[q], where
  2150. delta x[q] = delta x[p] / alfa[p,q] */
  2151. xassert(cval[cpiv] != 0.0);
  2152. new_x = x + (rval[rpiv] / cval[cpiv]) * delta;
  2153. store: /* store analysis results */
  2154. if (kase < 0)
  2155. { if (coef1 != NULL) *coef1 = lim_coef;
  2156. if (var1 != NULL) *var1 = q;
  2157. if (value1 != NULL) *value1 = new_x;
  2158. }
  2159. else
  2160. { if (coef2 != NULL) *coef2 = lim_coef;
  2161. if (var2 != NULL) *var2 = q;
  2162. if (value2 != NULL) *value2 = new_x;
  2163. }
  2164. }
  2165. /* free working arrays */
  2166. xfree(cind);
  2167. xfree(cval);
  2168. xfree(rind);
  2169. xfree(rval);
  2170. return;
  2171. }
  2172. /* eof */