You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1144 lines
38 KiB

  1. /* glpipm.c */
  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, 2011, 2013 Andrew Makhorin, Department for Applied
  7. * Informatics, Moscow Aviation Institute, Moscow, Russia. All rights
  8. * reserved. 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 "env.h"
  24. #include "glpipm.h"
  25. #include "glpmat.h"
  26. #define ITER_MAX 100
  27. /* maximal number of iterations */
  28. struct csa
  29. { /* common storage area */
  30. /*--------------------------------------------------------------*/
  31. /* LP data */
  32. int m;
  33. /* number of rows (equality constraints) */
  34. int n;
  35. /* number of columns (structural variables) */
  36. int *A_ptr; /* int A_ptr[1+m+1]; */
  37. int *A_ind; /* int A_ind[A_ptr[m+1]]; */
  38. double *A_val; /* double A_val[A_ptr[m+1]]; */
  39. /* mxn-matrix A in storage-by-rows format */
  40. double *b; /* double b[1+m]; */
  41. /* m-vector b of right-hand sides */
  42. double *c; /* double c[1+n]; */
  43. /* n-vector c of objective coefficients; c[0] is constant term of
  44. the objective function */
  45. /*--------------------------------------------------------------*/
  46. /* LP solution */
  47. double *x; /* double x[1+n]; */
  48. double *y; /* double y[1+m]; */
  49. double *z; /* double z[1+n]; */
  50. /* current point in primal-dual space; the best point on exit */
  51. /*--------------------------------------------------------------*/
  52. /* control parameters */
  53. const glp_iptcp *parm;
  54. /*--------------------------------------------------------------*/
  55. /* working arrays and variables */
  56. double *D; /* double D[1+n]; */
  57. /* diagonal nxn-matrix D = X*inv(Z), where X = diag(x[j]) and
  58. Z = diag(z[j]) */
  59. int *P; /* int P[1+m+m]; */
  60. /* permutation mxm-matrix P used to minimize fill-in in Cholesky
  61. factorization */
  62. int *S_ptr; /* int S_ptr[1+m+1]; */
  63. int *S_ind; /* int S_ind[S_ptr[m+1]]; */
  64. double *S_val; /* double S_val[S_ptr[m+1]]; */
  65. double *S_diag; /* double S_diag[1+m]; */
  66. /* symmetric mxm-matrix S = P*A*D*A'*P' whose upper triangular
  67. part without diagonal elements is stored in S_ptr, S_ind, and
  68. S_val in storage-by-rows format, diagonal elements are stored
  69. in S_diag */
  70. int *U_ptr; /* int U_ptr[1+m+1]; */
  71. int *U_ind; /* int U_ind[U_ptr[m+1]]; */
  72. double *U_val; /* double U_val[U_ptr[m+1]]; */
  73. double *U_diag; /* double U_diag[1+m]; */
  74. /* upper triangular mxm-matrix U defining Cholesky factorization
  75. S = U'*U; its non-diagonal elements are stored in U_ptr, U_ind,
  76. U_val in storage-by-rows format, diagonal elements are stored
  77. in U_diag */
  78. int iter;
  79. /* iteration number (0, 1, 2, ...); iter = 0 corresponds to the
  80. initial point */
  81. double obj;
  82. /* current value of the objective function */
  83. double rpi;
  84. /* relative primal infeasibility rpi = ||A*x-b||/(1+||b||) */
  85. double rdi;
  86. /* relative dual infeasibility rdi = ||A'*y+z-c||/(1+||c||) */
  87. double gap;
  88. /* primal-dual gap = |c'*x-b'*y|/(1+|c'*x|) which is a relative
  89. difference between primal and dual objective functions */
  90. double phi;
  91. /* merit function phi = ||A*x-b||/max(1,||b||) +
  92. + ||A'*y+z-c||/max(1,||c||) +
  93. + |c'*x-b'*y|/max(1,||b||,||c||) */
  94. double mu;
  95. /* duality measure mu = x'*z/n (used as barrier parameter) */
  96. double rmu;
  97. /* rmu = max(||A*x-b||,||A'*y+z-c||)/mu */
  98. double rmu0;
  99. /* the initial value of rmu on iteration 0 */
  100. double *phi_min; /* double phi_min[1+ITER_MAX]; */
  101. /* phi_min[k] = min(phi[k]), where phi[k] is the value of phi on
  102. k-th iteration, 0 <= k <= iter */
  103. int best_iter;
  104. /* iteration number, on which the value of phi reached its best
  105. (minimal) value */
  106. double *best_x; /* double best_x[1+n]; */
  107. double *best_y; /* double best_y[1+m]; */
  108. double *best_z; /* double best_z[1+n]; */
  109. /* best point (in the sense of the merit function phi) which has
  110. been reached on iteration iter_best */
  111. double best_obj;
  112. /* objective value at the best point */
  113. double *dx_aff; /* double dx_aff[1+n]; */
  114. double *dy_aff; /* double dy_aff[1+m]; */
  115. double *dz_aff; /* double dz_aff[1+n]; */
  116. /* affine scaling direction */
  117. double alfa_aff_p, alfa_aff_d;
  118. /* maximal primal and dual stepsizes in affine scaling direction,
  119. on which x and z are still non-negative */
  120. double mu_aff;
  121. /* duality measure mu_aff = x_aff'*z_aff/n in the boundary point
  122. x_aff' = x+alfa_aff_p*dx_aff, z_aff' = z+alfa_aff_d*dz_aff */
  123. double sigma;
  124. /* Mehrotra's heuristic parameter (0 <= sigma <= 1) */
  125. double *dx_cc; /* double dx_cc[1+n]; */
  126. double *dy_cc; /* double dy_cc[1+m]; */
  127. double *dz_cc; /* double dz_cc[1+n]; */
  128. /* centering corrector direction */
  129. double *dx; /* double dx[1+n]; */
  130. double *dy; /* double dy[1+m]; */
  131. double *dz; /* double dz[1+n]; */
  132. /* final combined direction dx = dx_aff+dx_cc, dy = dy_aff+dy_cc,
  133. dz = dz_aff+dz_cc */
  134. double alfa_max_p;
  135. double alfa_max_d;
  136. /* maximal primal and dual stepsizes in combined direction, on
  137. which x and z are still non-negative */
  138. };
  139. /***********************************************************************
  140. * initialize - allocate and initialize common storage area
  141. *
  142. * This routine allocates and initializes the common storage area (CSA)
  143. * used by interior-point method routines. */
  144. static void initialize(struct csa *csa)
  145. { int m = csa->m;
  146. int n = csa->n;
  147. int i;
  148. if (csa->parm->msg_lev >= GLP_MSG_ALL)
  149. xprintf("Matrix A has %d non-zeros\n", csa->A_ptr[m+1]-1);
  150. csa->D = xcalloc(1+n, sizeof(double));
  151. /* P := I */
  152. csa->P = xcalloc(1+m+m, sizeof(int));
  153. for (i = 1; i <= m; i++) csa->P[i] = csa->P[m+i] = i;
  154. /* S := A*A', symbolically */
  155. csa->S_ptr = xcalloc(1+m+1, sizeof(int));
  156. csa->S_ind = adat_symbolic(m, n, csa->P, csa->A_ptr, csa->A_ind,
  157. csa->S_ptr);
  158. if (csa->parm->msg_lev >= GLP_MSG_ALL)
  159. xprintf("Matrix S = A*A' has %d non-zeros (upper triangle)\n",
  160. csa->S_ptr[m+1]-1 + m);
  161. /* determine P using specified ordering algorithm */
  162. if (csa->parm->ord_alg == GLP_ORD_NONE)
  163. { if (csa->parm->msg_lev >= GLP_MSG_ALL)
  164. xprintf("Original ordering is being used\n");
  165. for (i = 1; i <= m; i++)
  166. csa->P[i] = csa->P[m+i] = i;
  167. }
  168. else if (csa->parm->ord_alg == GLP_ORD_QMD)
  169. { if (csa->parm->msg_lev >= GLP_MSG_ALL)
  170. xprintf("Minimum degree ordering (QMD)...\n");
  171. min_degree(m, csa->S_ptr, csa->S_ind, csa->P);
  172. }
  173. else if (csa->parm->ord_alg == GLP_ORD_AMD)
  174. { if (csa->parm->msg_lev >= GLP_MSG_ALL)
  175. xprintf("Approximate minimum degree ordering (AMD)...\n");
  176. amd_order1(m, csa->S_ptr, csa->S_ind, csa->P);
  177. }
  178. else if (csa->parm->ord_alg == GLP_ORD_SYMAMD)
  179. { if (csa->parm->msg_lev >= GLP_MSG_ALL)
  180. xprintf("Approximate minimum degree ordering (SYMAMD)...\n")
  181. ;
  182. symamd_ord(m, csa->S_ptr, csa->S_ind, csa->P);
  183. }
  184. else
  185. xassert(csa != csa);
  186. /* S := P*A*A'*P', symbolically */
  187. xfree(csa->S_ind);
  188. csa->S_ind = adat_symbolic(m, n, csa->P, csa->A_ptr, csa->A_ind,
  189. csa->S_ptr);
  190. csa->S_val = xcalloc(csa->S_ptr[m+1], sizeof(double));
  191. csa->S_diag = xcalloc(1+m, sizeof(double));
  192. /* compute Cholesky factorization S = U'*U, symbolically */
  193. if (csa->parm->msg_lev >= GLP_MSG_ALL)
  194. xprintf("Computing Cholesky factorization S = L*L'...\n");
  195. csa->U_ptr = xcalloc(1+m+1, sizeof(int));
  196. csa->U_ind = chol_symbolic(m, csa->S_ptr, csa->S_ind, csa->U_ptr);
  197. if (csa->parm->msg_lev >= GLP_MSG_ALL)
  198. xprintf("Matrix L has %d non-zeros\n", csa->U_ptr[m+1]-1 + m);
  199. csa->U_val = xcalloc(csa->U_ptr[m+1], sizeof(double));
  200. csa->U_diag = xcalloc(1+m, sizeof(double));
  201. csa->iter = 0;
  202. csa->obj = 0.0;
  203. csa->rpi = 0.0;
  204. csa->rdi = 0.0;
  205. csa->gap = 0.0;
  206. csa->phi = 0.0;
  207. csa->mu = 0.0;
  208. csa->rmu = 0.0;
  209. csa->rmu0 = 0.0;
  210. csa->phi_min = xcalloc(1+ITER_MAX, sizeof(double));
  211. csa->best_iter = 0;
  212. csa->best_x = xcalloc(1+n, sizeof(double));
  213. csa->best_y = xcalloc(1+m, sizeof(double));
  214. csa->best_z = xcalloc(1+n, sizeof(double));
  215. csa->best_obj = 0.0;
  216. csa->dx_aff = xcalloc(1+n, sizeof(double));
  217. csa->dy_aff = xcalloc(1+m, sizeof(double));
  218. csa->dz_aff = xcalloc(1+n, sizeof(double));
  219. csa->alfa_aff_p = 0.0;
  220. csa->alfa_aff_d = 0.0;
  221. csa->mu_aff = 0.0;
  222. csa->sigma = 0.0;
  223. csa->dx_cc = xcalloc(1+n, sizeof(double));
  224. csa->dy_cc = xcalloc(1+m, sizeof(double));
  225. csa->dz_cc = xcalloc(1+n, sizeof(double));
  226. csa->dx = csa->dx_aff;
  227. csa->dy = csa->dy_aff;
  228. csa->dz = csa->dz_aff;
  229. csa->alfa_max_p = 0.0;
  230. csa->alfa_max_d = 0.0;
  231. return;
  232. }
  233. /***********************************************************************
  234. * A_by_vec - compute y = A*x
  235. *
  236. * This routine computes matrix-vector product y = A*x, where A is the
  237. * constraint matrix. */
  238. static void A_by_vec(struct csa *csa, double x[], double y[])
  239. { /* compute y = A*x */
  240. int m = csa->m;
  241. int *A_ptr = csa->A_ptr;
  242. int *A_ind = csa->A_ind;
  243. double *A_val = csa->A_val;
  244. int i, t, beg, end;
  245. double temp;
  246. for (i = 1; i <= m; i++)
  247. { temp = 0.0;
  248. beg = A_ptr[i], end = A_ptr[i+1];
  249. for (t = beg; t < end; t++) temp += A_val[t] * x[A_ind[t]];
  250. y[i] = temp;
  251. }
  252. return;
  253. }
  254. /***********************************************************************
  255. * AT_by_vec - compute y = A'*x
  256. *
  257. * This routine computes matrix-vector product y = A'*x, where A' is a
  258. * matrix transposed to the constraint matrix A. */
  259. static void AT_by_vec(struct csa *csa, double x[], double y[])
  260. { /* compute y = A'*x, where A' is transposed to A */
  261. int m = csa->m;
  262. int n = csa->n;
  263. int *A_ptr = csa->A_ptr;
  264. int *A_ind = csa->A_ind;
  265. double *A_val = csa->A_val;
  266. int i, j, t, beg, end;
  267. double temp;
  268. for (j = 1; j <= n; j++) y[j] = 0.0;
  269. for (i = 1; i <= m; i++)
  270. { temp = x[i];
  271. if (temp == 0.0) continue;
  272. beg = A_ptr[i], end = A_ptr[i+1];
  273. for (t = beg; t < end; t++) y[A_ind[t]] += A_val[t] * temp;
  274. }
  275. return;
  276. }
  277. /***********************************************************************
  278. * decomp_NE - numeric factorization of matrix S = P*A*D*A'*P'
  279. *
  280. * This routine implements numeric phase of Cholesky factorization of
  281. * the matrix S = P*A*D*A'*P', which is a permuted matrix of the normal
  282. * equation system. Matrix D is assumed to be already computed. */
  283. static void decomp_NE(struct csa *csa)
  284. { adat_numeric(csa->m, csa->n, csa->P, csa->A_ptr, csa->A_ind,
  285. csa->A_val, csa->D, csa->S_ptr, csa->S_ind, csa->S_val,
  286. csa->S_diag);
  287. chol_numeric(csa->m, csa->S_ptr, csa->S_ind, csa->S_val,
  288. csa->S_diag, csa->U_ptr, csa->U_ind, csa->U_val, csa->U_diag);
  289. return;
  290. }
  291. /***********************************************************************
  292. * solve_NE - solve normal equation system
  293. *
  294. * This routine solves the normal equation system:
  295. *
  296. * A*D*A'*y = h.
  297. *
  298. * It is assumed that the matrix A*D*A' has been previously factorized
  299. * by the routine decomp_NE.
  300. *
  301. * On entry the array y contains the vector of right-hand sides h. On
  302. * exit this array contains the computed vector of unknowns y.
  303. *
  304. * Once the vector y has been computed the routine checks for numeric
  305. * stability. If the residual vector:
  306. *
  307. * r = A*D*A'*y - h
  308. *
  309. * is relatively small, the routine returns zero, otherwise non-zero is
  310. * returned. */
  311. static int solve_NE(struct csa *csa, double y[])
  312. { int m = csa->m;
  313. int n = csa->n;
  314. int *P = csa->P;
  315. int i, j, ret = 0;
  316. double *h, *r, *w;
  317. /* save vector of right-hand sides h */
  318. h = xcalloc(1+m, sizeof(double));
  319. for (i = 1; i <= m; i++) h[i] = y[i];
  320. /* solve normal equation system (A*D*A')*y = h */
  321. /* since S = P*A*D*A'*P' = U'*U, then A*D*A' = P'*U'*U*P, so we
  322. have inv(A*D*A') = P'*inv(U)*inv(U')*P */
  323. /* w := P*h */
  324. w = xcalloc(1+m, sizeof(double));
  325. for (i = 1; i <= m; i++) w[i] = y[P[i]];
  326. /* w := inv(U')*w */
  327. ut_solve(m, csa->U_ptr, csa->U_ind, csa->U_val, csa->U_diag, w);
  328. /* w := inv(U)*w */
  329. u_solve(m, csa->U_ptr, csa->U_ind, csa->U_val, csa->U_diag, w);
  330. /* y := P'*w */
  331. for (i = 1; i <= m; i++) y[i] = w[P[m+i]];
  332. xfree(w);
  333. /* compute residual vector r = A*D*A'*y - h */
  334. r = xcalloc(1+m, sizeof(double));
  335. /* w := A'*y */
  336. w = xcalloc(1+n, sizeof(double));
  337. AT_by_vec(csa, y, w);
  338. /* w := D*w */
  339. for (j = 1; j <= n; j++) w[j] *= csa->D[j];
  340. /* r := A*w */
  341. A_by_vec(csa, w, r);
  342. xfree(w);
  343. /* r := r - h */
  344. for (i = 1; i <= m; i++) r[i] -= h[i];
  345. /* check for numeric stability */
  346. for (i = 1; i <= m; i++)
  347. { if (fabs(r[i]) / (1.0 + fabs(h[i])) > 1e-4)
  348. { ret = 1;
  349. break;
  350. }
  351. }
  352. xfree(h);
  353. xfree(r);
  354. return ret;
  355. }
  356. /***********************************************************************
  357. * solve_NS - solve Newtonian system
  358. *
  359. * This routine solves the Newtonian system:
  360. *
  361. * A*dx = p
  362. *
  363. * A'*dy + dz = q
  364. *
  365. * Z*dx + X*dz = r
  366. *
  367. * where X = diag(x[j]), Z = diag(z[j]), by reducing it to the normal
  368. * equation system:
  369. *
  370. * (A*inv(Z)*X*A')*dy = A*inv(Z)*(X*q-r)+p
  371. *
  372. * (it is assumed that the matrix A*inv(Z)*X*A' has been factorized by
  373. * the routine decomp_NE).
  374. *
  375. * Once vector dy has been computed the routine computes vectors dx and
  376. * dz as follows:
  377. *
  378. * dx = inv(Z)*(X*(A'*dy-q)+r)
  379. *
  380. * dz = inv(X)*(r-Z*dx)
  381. *
  382. * The routine solve_NS returns the same code which was reported by the
  383. * routine solve_NE (see above). */
  384. static int solve_NS(struct csa *csa, double p[], double q[], double r[],
  385. double dx[], double dy[], double dz[])
  386. { int m = csa->m;
  387. int n = csa->n;
  388. double *x = csa->x;
  389. double *z = csa->z;
  390. int i, j, ret;
  391. double *w = dx;
  392. /* compute the vector of right-hand sides A*inv(Z)*(X*q-r)+p for
  393. the normal equation system */
  394. for (j = 1; j <= n; j++)
  395. w[j] = (x[j] * q[j] - r[j]) / z[j];
  396. A_by_vec(csa, w, dy);
  397. for (i = 1; i <= m; i++) dy[i] += p[i];
  398. /* solve the normal equation system to compute vector dy */
  399. ret = solve_NE(csa, dy);
  400. /* compute vectors dx and dz */
  401. AT_by_vec(csa, dy, dx);
  402. for (j = 1; j <= n; j++)
  403. { dx[j] = (x[j] * (dx[j] - q[j]) + r[j]) / z[j];
  404. dz[j] = (r[j] - z[j] * dx[j]) / x[j];
  405. }
  406. return ret;
  407. }
  408. /***********************************************************************
  409. * initial_point - choose initial point using Mehrotra's heuristic
  410. *
  411. * This routine chooses a starting point using a heuristic proposed in
  412. * the paper:
  413. *
  414. * S. Mehrotra. On the implementation of a primal-dual interior point
  415. * method. SIAM J. on Optim., 2(4), pp. 575-601, 1992.
  416. *
  417. * The starting point x in the primal space is chosen as a solution of
  418. * the following least squares problem:
  419. *
  420. * minimize ||x||
  421. *
  422. * subject to A*x = b
  423. *
  424. * which can be computed explicitly as follows:
  425. *
  426. * x = A'*inv(A*A')*b
  427. *
  428. * Similarly, the starting point (y, z) in the dual space is chosen as
  429. * a solution of the following least squares problem:
  430. *
  431. * minimize ||z||
  432. *
  433. * subject to A'*y + z = c
  434. *
  435. * which can be computed explicitly as follows:
  436. *
  437. * y = inv(A*A')*A*c
  438. *
  439. * z = c - A'*y
  440. *
  441. * However, some components of the vectors x and z may be non-positive
  442. * or close to zero, so the routine uses a Mehrotra's heuristic to find
  443. * a more appropriate starting point. */
  444. static void initial_point(struct csa *csa)
  445. { int m = csa->m;
  446. int n = csa->n;
  447. double *b = csa->b;
  448. double *c = csa->c;
  449. double *x = csa->x;
  450. double *y = csa->y;
  451. double *z = csa->z;
  452. double *D = csa->D;
  453. int i, j;
  454. double dp, dd, ex, ez, xz;
  455. /* factorize A*A' */
  456. for (j = 1; j <= n; j++) D[j] = 1.0;
  457. decomp_NE(csa);
  458. /* x~ = A'*inv(A*A')*b */
  459. for (i = 1; i <= m; i++) y[i] = b[i];
  460. solve_NE(csa, y);
  461. AT_by_vec(csa, y, x);
  462. /* y~ = inv(A*A')*A*c */
  463. A_by_vec(csa, c, y);
  464. solve_NE(csa, y);
  465. /* z~ = c - A'*y~ */
  466. AT_by_vec(csa, y,z);
  467. for (j = 1; j <= n; j++) z[j] = c[j] - z[j];
  468. /* use Mehrotra's heuristic in order to choose more appropriate
  469. starting point with positive components of vectors x and z */
  470. dp = dd = 0.0;
  471. for (j = 1; j <= n; j++)
  472. { if (dp < -1.5 * x[j]) dp = -1.5 * x[j];
  473. if (dd < -1.5 * z[j]) dd = -1.5 * z[j];
  474. }
  475. /* note that b = 0 involves x = 0, and c = 0 involves y = 0 and
  476. z = 0, so we need to be careful */
  477. if (dp == 0.0) dp = 1.5;
  478. if (dd == 0.0) dd = 1.5;
  479. ex = ez = xz = 0.0;
  480. for (j = 1; j <= n; j++)
  481. { ex += (x[j] + dp);
  482. ez += (z[j] + dd);
  483. xz += (x[j] + dp) * (z[j] + dd);
  484. }
  485. dp += 0.5 * (xz / ez);
  486. dd += 0.5 * (xz / ex);
  487. for (j = 1; j <= n; j++)
  488. { x[j] += dp;
  489. z[j] += dd;
  490. xassert(x[j] > 0.0 && z[j] > 0.0);
  491. }
  492. return;
  493. }
  494. /***********************************************************************
  495. * basic_info - perform basic computations at the current point
  496. *
  497. * This routine computes the following quantities at the current point:
  498. *
  499. * 1) value of the objective function:
  500. *
  501. * F = c'*x + c[0]
  502. *
  503. * 2) relative primal infeasibility:
  504. *
  505. * rpi = ||A*x-b|| / (1+||b||)
  506. *
  507. * 3) relative dual infeasibility:
  508. *
  509. * rdi = ||A'*y+z-c|| / (1+||c||)
  510. *
  511. * 4) primal-dual gap (relative difference between the primal and the
  512. * dual objective function values):
  513. *
  514. * gap = |c'*x-b'*y| / (1+|c'*x|)
  515. *
  516. * 5) merit function:
  517. *
  518. * phi = ||A*x-b|| / max(1,||b||) + ||A'*y+z-c|| / max(1,||c||) +
  519. *
  520. * + |c'*x-b'*y| / max(1,||b||,||c||)
  521. *
  522. * 6) duality measure:
  523. *
  524. * mu = x'*z / n
  525. *
  526. * 7) the ratio of infeasibility to mu:
  527. *
  528. * rmu = max(||A*x-b||,||A'*y+z-c||) / mu
  529. *
  530. * where ||*|| denotes euclidian norm, *' denotes transposition. */
  531. static void basic_info(struct csa *csa)
  532. { int m = csa->m;
  533. int n = csa->n;
  534. double *b = csa->b;
  535. double *c = csa->c;
  536. double *x = csa->x;
  537. double *y = csa->y;
  538. double *z = csa->z;
  539. int i, j;
  540. double norm1, bnorm, norm2, cnorm, cx, by, *work, temp;
  541. /* compute value of the objective function */
  542. temp = c[0];
  543. for (j = 1; j <= n; j++) temp += c[j] * x[j];
  544. csa->obj = temp;
  545. /* norm1 = ||A*x-b|| */
  546. work = xcalloc(1+m, sizeof(double));
  547. A_by_vec(csa, x, work);
  548. norm1 = 0.0;
  549. for (i = 1; i <= m; i++)
  550. norm1 += (work[i] - b[i]) * (work[i] - b[i]);
  551. norm1 = sqrt(norm1);
  552. xfree(work);
  553. /* bnorm = ||b|| */
  554. bnorm = 0.0;
  555. for (i = 1; i <= m; i++) bnorm += b[i] * b[i];
  556. bnorm = sqrt(bnorm);
  557. /* compute relative primal infeasibility */
  558. csa->rpi = norm1 / (1.0 + bnorm);
  559. /* norm2 = ||A'*y+z-c|| */
  560. work = xcalloc(1+n, sizeof(double));
  561. AT_by_vec(csa, y, work);
  562. norm2 = 0.0;
  563. for (j = 1; j <= n; j++)
  564. norm2 += (work[j] + z[j] - c[j]) * (work[j] + z[j] - c[j]);
  565. norm2 = sqrt(norm2);
  566. xfree(work);
  567. /* cnorm = ||c|| */
  568. cnorm = 0.0;
  569. for (j = 1; j <= n; j++) cnorm += c[j] * c[j];
  570. cnorm = sqrt(cnorm);
  571. /* compute relative dual infeasibility */
  572. csa->rdi = norm2 / (1.0 + cnorm);
  573. /* by = b'*y */
  574. by = 0.0;
  575. for (i = 1; i <= m; i++) by += b[i] * y[i];
  576. /* cx = c'*x */
  577. cx = 0.0;
  578. for (j = 1; j <= n; j++) cx += c[j] * x[j];
  579. /* compute primal-dual gap */
  580. csa->gap = fabs(cx - by) / (1.0 + fabs(cx));
  581. /* compute merit function */
  582. csa->phi = 0.0;
  583. csa->phi += norm1 / (bnorm > 1.0 ? bnorm : 1.0);
  584. csa->phi += norm2 / (cnorm > 1.0 ? cnorm : 1.0);
  585. temp = 1.0;
  586. if (temp < bnorm) temp = bnorm;
  587. if (temp < cnorm) temp = cnorm;
  588. csa->phi += fabs(cx - by) / temp;
  589. /* compute duality measure */
  590. temp = 0.0;
  591. for (j = 1; j <= n; j++) temp += x[j] * z[j];
  592. csa->mu = temp / (double)n;
  593. /* compute the ratio of infeasibility to mu */
  594. csa->rmu = (norm1 > norm2 ? norm1 : norm2) / csa->mu;
  595. return;
  596. }
  597. /***********************************************************************
  598. * make_step - compute next point using Mehrotra's technique
  599. *
  600. * This routine computes the next point using the predictor-corrector
  601. * technique proposed in the paper:
  602. *
  603. * S. Mehrotra. On the implementation of a primal-dual interior point
  604. * method. SIAM J. on Optim., 2(4), pp. 575-601, 1992.
  605. *
  606. * At first, the routine computes so called affine scaling (predictor)
  607. * direction (dx_aff,dy_aff,dz_aff) which is a solution of the system:
  608. *
  609. * A*dx_aff = b - A*x
  610. *
  611. * A'*dy_aff + dz_aff = c - A'*y - z
  612. *
  613. * Z*dx_aff + X*dz_aff = - X*Z*e
  614. *
  615. * where (x,y,z) is the current point, X = diag(x[j]), Z = diag(z[j]),
  616. * e = (1,...,1)'.
  617. *
  618. * Then, the routine computes the centering parameter sigma, using the
  619. * following Mehrotra's heuristic:
  620. *
  621. * alfa_aff_p = inf{0 <= alfa <= 1 | x+alfa*dx_aff >= 0}
  622. *
  623. * alfa_aff_d = inf{0 <= alfa <= 1 | z+alfa*dz_aff >= 0}
  624. *
  625. * mu_aff = (x+alfa_aff_p*dx_aff)'*(z+alfa_aff_d*dz_aff)/n
  626. *
  627. * sigma = (mu_aff/mu)^3
  628. *
  629. * where alfa_aff_p is the maximal stepsize along the affine scaling
  630. * direction in the primal space, alfa_aff_d is the maximal stepsize
  631. * along the same direction in the dual space.
  632. *
  633. * After determining sigma the routine computes so called centering
  634. * (corrector) direction (dx_cc,dy_cc,dz_cc) which is the solution of
  635. * the system:
  636. *
  637. * A*dx_cc = 0
  638. *
  639. * A'*dy_cc + dz_cc = 0
  640. *
  641. * Z*dx_cc + X*dz_cc = sigma*mu*e - X*Z*e
  642. *
  643. * Finally, the routine computes the combined direction
  644. *
  645. * (dx,dy,dz) = (dx_aff,dy_aff,dz_aff) + (dx_cc,dy_cc,dz_cc)
  646. *
  647. * and determines maximal primal and dual stepsizes along the combined
  648. * direction:
  649. *
  650. * alfa_max_p = inf{0 <= alfa <= 1 | x+alfa*dx >= 0}
  651. *
  652. * alfa_max_d = inf{0 <= alfa <= 1 | z+alfa*dz >= 0}
  653. *
  654. * In order to prevent the next point to be too close to the boundary
  655. * of the positive ortant, the routine decreases maximal stepsizes:
  656. *
  657. * alfa_p = gamma_p * alfa_max_p
  658. *
  659. * alfa_d = gamma_d * alfa_max_d
  660. *
  661. * where gamma_p and gamma_d are scaling factors, and computes the next
  662. * point:
  663. *
  664. * x_new = x + alfa_p * dx
  665. *
  666. * y_new = y + alfa_d * dy
  667. *
  668. * z_new = z + alfa_d * dz
  669. *
  670. * which becomes the current point on the next iteration. */
  671. static int make_step(struct csa *csa)
  672. { int m = csa->m;
  673. int n = csa->n;
  674. double *b = csa->b;
  675. double *c = csa->c;
  676. double *x = csa->x;
  677. double *y = csa->y;
  678. double *z = csa->z;
  679. double *dx_aff = csa->dx_aff;
  680. double *dy_aff = csa->dy_aff;
  681. double *dz_aff = csa->dz_aff;
  682. double *dx_cc = csa->dx_cc;
  683. double *dy_cc = csa->dy_cc;
  684. double *dz_cc = csa->dz_cc;
  685. double *dx = csa->dx;
  686. double *dy = csa->dy;
  687. double *dz = csa->dz;
  688. int i, j, ret = 0;
  689. double temp, gamma_p, gamma_d, *p, *q, *r;
  690. /* allocate working arrays */
  691. p = xcalloc(1+m, sizeof(double));
  692. q = xcalloc(1+n, sizeof(double));
  693. r = xcalloc(1+n, sizeof(double));
  694. /* p = b - A*x */
  695. A_by_vec(csa, x, p);
  696. for (i = 1; i <= m; i++) p[i] = b[i] - p[i];
  697. /* q = c - A'*y - z */
  698. AT_by_vec(csa, y,q);
  699. for (j = 1; j <= n; j++) q[j] = c[j] - q[j] - z[j];
  700. /* r = - X * Z * e */
  701. for (j = 1; j <= n; j++) r[j] = - x[j] * z[j];
  702. /* solve the first Newtonian system */
  703. if (solve_NS(csa, p, q, r, dx_aff, dy_aff, dz_aff))
  704. { ret = 1;
  705. goto done;
  706. }
  707. /* alfa_aff_p = inf{0 <= alfa <= 1 | x + alfa*dx_aff >= 0} */
  708. /* alfa_aff_d = inf{0 <= alfa <= 1 | z + alfa*dz_aff >= 0} */
  709. csa->alfa_aff_p = csa->alfa_aff_d = 1.0;
  710. for (j = 1; j <= n; j++)
  711. { if (dx_aff[j] < 0.0)
  712. { temp = - x[j] / dx_aff[j];
  713. if (csa->alfa_aff_p > temp) csa->alfa_aff_p = temp;
  714. }
  715. if (dz_aff[j] < 0.0)
  716. { temp = - z[j] / dz_aff[j];
  717. if (csa->alfa_aff_d > temp) csa->alfa_aff_d = temp;
  718. }
  719. }
  720. /* mu_aff = (x+alfa_aff_p*dx_aff)' * (z+alfa_aff_d*dz_aff) / n */
  721. temp = 0.0;
  722. for (j = 1; j <= n; j++)
  723. temp += (x[j] + csa->alfa_aff_p * dx_aff[j]) *
  724. (z[j] + csa->alfa_aff_d * dz_aff[j]);
  725. csa->mu_aff = temp / (double)n;
  726. /* sigma = (mu_aff/mu)^3 */
  727. temp = csa->mu_aff / csa->mu;
  728. csa->sigma = temp * temp * temp;
  729. /* p = 0 */
  730. for (i = 1; i <= m; i++) p[i] = 0.0;
  731. /* q = 0 */
  732. for (j = 1; j <= n; j++) q[j] = 0.0;
  733. /* r = sigma * mu * e - X * Z * e */
  734. for (j = 1; j <= n; j++)
  735. r[j] = csa->sigma * csa->mu - dx_aff[j] * dz_aff[j];
  736. /* solve the second Newtonian system with the same coefficients
  737. but with altered right-hand sides */
  738. if (solve_NS(csa, p, q, r, dx_cc, dy_cc, dz_cc))
  739. { ret = 1;
  740. goto done;
  741. }
  742. /* (dx,dy,dz) = (dx_aff,dy_aff,dz_aff) + (dx_cc,dy_cc,dz_cc) */
  743. for (j = 1; j <= n; j++) dx[j] = dx_aff[j] + dx_cc[j];
  744. for (i = 1; i <= m; i++) dy[i] = dy_aff[i] + dy_cc[i];
  745. for (j = 1; j <= n; j++) dz[j] = dz_aff[j] + dz_cc[j];
  746. /* alfa_max_p = inf{0 <= alfa <= 1 | x + alfa*dx >= 0} */
  747. /* alfa_max_d = inf{0 <= alfa <= 1 | z + alfa*dz >= 0} */
  748. csa->alfa_max_p = csa->alfa_max_d = 1.0;
  749. for (j = 1; j <= n; j++)
  750. { if (dx[j] < 0.0)
  751. { temp = - x[j] / dx[j];
  752. if (csa->alfa_max_p > temp) csa->alfa_max_p = temp;
  753. }
  754. if (dz[j] < 0.0)
  755. { temp = - z[j] / dz[j];
  756. if (csa->alfa_max_d > temp) csa->alfa_max_d = temp;
  757. }
  758. }
  759. /* determine scale factors (not implemented yet) */
  760. gamma_p = 0.90;
  761. gamma_d = 0.90;
  762. /* compute the next point */
  763. for (j = 1; j <= n; j++)
  764. { x[j] += gamma_p * csa->alfa_max_p * dx[j];
  765. xassert(x[j] > 0.0);
  766. }
  767. for (i = 1; i <= m; i++)
  768. y[i] += gamma_d * csa->alfa_max_d * dy[i];
  769. for (j = 1; j <= n; j++)
  770. { z[j] += gamma_d * csa->alfa_max_d * dz[j];
  771. xassert(z[j] > 0.0);
  772. }
  773. done: /* free working arrays */
  774. xfree(p);
  775. xfree(q);
  776. xfree(r);
  777. return ret;
  778. }
  779. /***********************************************************************
  780. * terminate - deallocate common storage area
  781. *
  782. * This routine frees all memory allocated to the common storage area
  783. * used by interior-point method routines. */
  784. static void terminate(struct csa *csa)
  785. { xfree(csa->D);
  786. xfree(csa->P);
  787. xfree(csa->S_ptr);
  788. xfree(csa->S_ind);
  789. xfree(csa->S_val);
  790. xfree(csa->S_diag);
  791. xfree(csa->U_ptr);
  792. xfree(csa->U_ind);
  793. xfree(csa->U_val);
  794. xfree(csa->U_diag);
  795. xfree(csa->phi_min);
  796. xfree(csa->best_x);
  797. xfree(csa->best_y);
  798. xfree(csa->best_z);
  799. xfree(csa->dx_aff);
  800. xfree(csa->dy_aff);
  801. xfree(csa->dz_aff);
  802. xfree(csa->dx_cc);
  803. xfree(csa->dy_cc);
  804. xfree(csa->dz_cc);
  805. return;
  806. }
  807. /***********************************************************************
  808. * ipm_main - main interior-point method routine
  809. *
  810. * This is a main routine of the primal-dual interior-point method.
  811. *
  812. * The routine ipm_main returns one of the following codes:
  813. *
  814. * 0 - optimal solution found;
  815. * 1 - problem has no feasible (primal or dual) solution;
  816. * 2 - no convergence;
  817. * 3 - iteration limit exceeded;
  818. * 4 - numeric instability on solving Newtonian system.
  819. *
  820. * In case of non-zero return code the routine returns the best point,
  821. * which has been reached during optimization. */
  822. static int ipm_main(struct csa *csa)
  823. { int m = csa->m;
  824. int n = csa->n;
  825. int i, j, status;
  826. double temp;
  827. /* choose initial point using Mehrotra's heuristic */
  828. if (csa->parm->msg_lev >= GLP_MSG_ALL)
  829. xprintf("Guessing initial point...\n");
  830. initial_point(csa);
  831. /* main loop starts here */
  832. if (csa->parm->msg_lev >= GLP_MSG_ALL)
  833. xprintf("Optimization begins...\n");
  834. for (;;)
  835. { /* perform basic computations at the current point */
  836. basic_info(csa);
  837. /* save initial value of rmu */
  838. if (csa->iter == 0) csa->rmu0 = csa->rmu;
  839. /* accumulate values of min(phi[k]) and save the best point */
  840. xassert(csa->iter <= ITER_MAX);
  841. if (csa->iter == 0 || csa->phi_min[csa->iter-1] > csa->phi)
  842. { csa->phi_min[csa->iter] = csa->phi;
  843. csa->best_iter = csa->iter;
  844. for (j = 1; j <= n; j++) csa->best_x[j] = csa->x[j];
  845. for (i = 1; i <= m; i++) csa->best_y[i] = csa->y[i];
  846. for (j = 1; j <= n; j++) csa->best_z[j] = csa->z[j];
  847. csa->best_obj = csa->obj;
  848. }
  849. else
  850. csa->phi_min[csa->iter] = csa->phi_min[csa->iter-1];
  851. /* display information at the current point */
  852. if (csa->parm->msg_lev >= GLP_MSG_ON)
  853. xprintf("%3d: obj = %17.9e; rpi = %8.1e; rdi = %8.1e; gap ="
  854. " %8.1e\n", csa->iter, csa->obj, csa->rpi, csa->rdi,
  855. csa->gap);
  856. /* check if the current point is optimal */
  857. if (csa->rpi < 1e-8 && csa->rdi < 1e-8 && csa->gap < 1e-8)
  858. { if (csa->parm->msg_lev >= GLP_MSG_ALL)
  859. xprintf("OPTIMAL SOLUTION FOUND\n");
  860. status = 0;
  861. break;
  862. }
  863. /* check if the problem has no feasible solution */
  864. temp = 1e5 * csa->phi_min[csa->iter];
  865. if (temp < 1e-8) temp = 1e-8;
  866. if (csa->phi >= temp)
  867. { if (csa->parm->msg_lev >= GLP_MSG_ALL)
  868. xprintf("PROBLEM HAS NO FEASIBLE PRIMAL/DUAL SOLUTION\n")
  869. ;
  870. status = 1;
  871. break;
  872. }
  873. /* check for very slow convergence or divergence */
  874. if (((csa->rpi >= 1e-8 || csa->rdi >= 1e-8) && csa->rmu /
  875. csa->rmu0 >= 1e6) ||
  876. (csa->iter >= 30 && csa->phi_min[csa->iter] >= 0.5 *
  877. csa->phi_min[csa->iter - 30]))
  878. { if (csa->parm->msg_lev >= GLP_MSG_ALL)
  879. xprintf("NO CONVERGENCE; SEARCH TERMINATED\n");
  880. status = 2;
  881. break;
  882. }
  883. /* check for maximal number of iterations */
  884. if (csa->iter == ITER_MAX)
  885. { if (csa->parm->msg_lev >= GLP_MSG_ALL)
  886. xprintf("ITERATION LIMIT EXCEEDED; SEARCH TERMINATED\n");
  887. status = 3;
  888. break;
  889. }
  890. /* start the next iteration */
  891. csa->iter++;
  892. /* factorize normal equation system */
  893. for (j = 1; j <= n; j++) csa->D[j] = csa->x[j] / csa->z[j];
  894. decomp_NE(csa);
  895. /* compute the next point using Mehrotra's predictor-corrector
  896. technique */
  897. if (make_step(csa))
  898. { if (csa->parm->msg_lev >= GLP_MSG_ALL)
  899. xprintf("NUMERIC INSTABILITY; SEARCH TERMINATED\n");
  900. status = 4;
  901. break;
  902. }
  903. }
  904. /* restore the best point */
  905. if (status != 0)
  906. { for (j = 1; j <= n; j++) csa->x[j] = csa->best_x[j];
  907. for (i = 1; i <= m; i++) csa->y[i] = csa->best_y[i];
  908. for (j = 1; j <= n; j++) csa->z[j] = csa->best_z[j];
  909. if (csa->parm->msg_lev >= GLP_MSG_ALL)
  910. xprintf("Best point %17.9e was reached on iteration %d\n",
  911. csa->best_obj, csa->best_iter);
  912. }
  913. /* return to the calling program */
  914. return status;
  915. }
  916. /***********************************************************************
  917. * NAME
  918. *
  919. * ipm_solve - core LP solver based on the interior-point method
  920. *
  921. * SYNOPSIS
  922. *
  923. * #include "glpipm.h"
  924. * int ipm_solve(glp_prob *P, const glp_iptcp *parm);
  925. *
  926. * DESCRIPTION
  927. *
  928. * The routine ipm_solve is a core LP solver based on the primal-dual
  929. * interior-point method.
  930. *
  931. * The routine assumes the following standard formulation of LP problem
  932. * to be solved:
  933. *
  934. * minimize
  935. *
  936. * F = c[0] + c[1]*x[1] + c[2]*x[2] + ... + c[n]*x[n]
  937. *
  938. * subject to linear constraints
  939. *
  940. * a[1,1]*x[1] + a[1,2]*x[2] + ... + a[1,n]*x[n] = b[1]
  941. *
  942. * a[2,1]*x[1] + a[2,2]*x[2] + ... + a[2,n]*x[n] = b[2]
  943. *
  944. * . . . . . .
  945. *
  946. * a[m,1]*x[1] + a[m,2]*x[2] + ... + a[m,n]*x[n] = b[m]
  947. *
  948. * and non-negative variables
  949. *
  950. * x[1] >= 0, x[2] >= 0, ..., x[n] >= 0
  951. *
  952. * where:
  953. * F is the objective function;
  954. * x[1], ..., x[n] are (structural) variables;
  955. * c[0] is a constant term of the objective function;
  956. * c[1], ..., c[n] are objective coefficients;
  957. * a[1,1], ..., a[m,n] are constraint coefficients;
  958. * b[1], ..., b[n] are right-hand sides.
  959. *
  960. * The solution is three vectors x, y, and z, which are stored by the
  961. * routine in the arrays x, y, and z, respectively. These vectors
  962. * correspond to the best primal-dual point found during optimization.
  963. * They are approximate solution of the following system (which is the
  964. * Karush-Kuhn-Tucker optimality conditions):
  965. *
  966. * A*x = b (primal feasibility condition)
  967. *
  968. * A'*y + z = c (dual feasibility condition)
  969. *
  970. * x'*z = 0 (primal-dual complementarity condition)
  971. *
  972. * x >= 0, z >= 0 (non-negativity condition)
  973. *
  974. * where:
  975. * x[1], ..., x[n] are primal (structural) variables;
  976. * y[1], ..., y[m] are dual variables (Lagrange multipliers) for
  977. * equality constraints;
  978. * z[1], ..., z[n] are dual variables (Lagrange multipliers) for
  979. * non-negativity constraints.
  980. *
  981. * RETURNS
  982. *
  983. * 0 LP has been successfully solved.
  984. *
  985. * GLP_ENOCVG
  986. * No convergence.
  987. *
  988. * GLP_EITLIM
  989. * Iteration limit exceeded.
  990. *
  991. * GLP_EINSTAB
  992. * Numeric instability on solving Newtonian system.
  993. *
  994. * In case of non-zero return code the routine returns the best point,
  995. * which has been reached during optimization. */
  996. int ipm_solve(glp_prob *P, const glp_iptcp *parm)
  997. { struct csa _dsa, *csa = &_dsa;
  998. int m = P->m;
  999. int n = P->n;
  1000. int nnz = P->nnz;
  1001. GLPROW *row;
  1002. GLPCOL *col;
  1003. GLPAIJ *aij;
  1004. int i, j, loc, ret, *A_ind, *A_ptr;
  1005. double dir, *A_val, *b, *c, *x, *y, *z;
  1006. xassert(m > 0);
  1007. xassert(n > 0);
  1008. /* allocate working arrays */
  1009. A_ptr = xcalloc(1+m+1, sizeof(int));
  1010. A_ind = xcalloc(1+nnz, sizeof(int));
  1011. A_val = xcalloc(1+nnz, sizeof(double));
  1012. b = xcalloc(1+m, sizeof(double));
  1013. c = xcalloc(1+n, sizeof(double));
  1014. x = xcalloc(1+n, sizeof(double));
  1015. y = xcalloc(1+m, sizeof(double));
  1016. z = xcalloc(1+n, sizeof(double));
  1017. /* prepare rows and constraint coefficients */
  1018. loc = 1;
  1019. for (i = 1; i <= m; i++)
  1020. { row = P->row[i];
  1021. xassert(row->type == GLP_FX);
  1022. b[i] = row->lb * row->rii;
  1023. A_ptr[i] = loc;
  1024. for (aij = row->ptr; aij != NULL; aij = aij->r_next)
  1025. { A_ind[loc] = aij->col->j;
  1026. A_val[loc] = row->rii * aij->val * aij->col->sjj;
  1027. loc++;
  1028. }
  1029. }
  1030. A_ptr[m+1] = loc;
  1031. xassert(loc-1 == nnz);
  1032. /* prepare columns and objective coefficients */
  1033. if (P->dir == GLP_MIN)
  1034. dir = +1.0;
  1035. else if (P->dir == GLP_MAX)
  1036. dir = -1.0;
  1037. else
  1038. xassert(P != P);
  1039. c[0] = dir * P->c0;
  1040. for (j = 1; j <= n; j++)
  1041. { col = P->col[j];
  1042. xassert(col->type == GLP_LO && col->lb == 0.0);
  1043. c[j] = dir * col->coef * col->sjj;
  1044. }
  1045. /* allocate and initialize the common storage area */
  1046. csa->m = m;
  1047. csa->n = n;
  1048. csa->A_ptr = A_ptr;
  1049. csa->A_ind = A_ind;
  1050. csa->A_val = A_val;
  1051. csa->b = b;
  1052. csa->c = c;
  1053. csa->x = x;
  1054. csa->y = y;
  1055. csa->z = z;
  1056. csa->parm = parm;
  1057. initialize(csa);
  1058. /* solve LP with the interior-point method */
  1059. ret = ipm_main(csa);
  1060. /* deallocate the common storage area */
  1061. terminate(csa);
  1062. /* determine solution status */
  1063. if (ret == 0)
  1064. { /* optimal solution found */
  1065. P->ipt_stat = GLP_OPT;
  1066. ret = 0;
  1067. }
  1068. else if (ret == 1)
  1069. { /* problem has no feasible (primal or dual) solution */
  1070. P->ipt_stat = GLP_NOFEAS;
  1071. ret = 0;
  1072. }
  1073. else if (ret == 2)
  1074. { /* no convergence */
  1075. P->ipt_stat = GLP_INFEAS;
  1076. ret = GLP_ENOCVG;
  1077. }
  1078. else if (ret == 3)
  1079. { /* iteration limit exceeded */
  1080. P->ipt_stat = GLP_INFEAS;
  1081. ret = GLP_EITLIM;
  1082. }
  1083. else if (ret == 4)
  1084. { /* numeric instability on solving Newtonian system */
  1085. P->ipt_stat = GLP_INFEAS;
  1086. ret = GLP_EINSTAB;
  1087. }
  1088. else
  1089. xassert(ret != ret);
  1090. /* store row solution components */
  1091. for (i = 1; i <= m; i++)
  1092. { row = P->row[i];
  1093. row->pval = row->lb;
  1094. row->dval = dir * y[i] * row->rii;
  1095. }
  1096. /* store column solution components */
  1097. P->ipt_obj = P->c0;
  1098. for (j = 1; j <= n; j++)
  1099. { col = P->col[j];
  1100. col->pval = x[j] * col->sjj;
  1101. col->dval = dir * z[j] / col->sjj;
  1102. P->ipt_obj += col->coef * col->pval;
  1103. }
  1104. /* free working arrays */
  1105. xfree(A_ptr);
  1106. xfree(A_ind);
  1107. xfree(A_val);
  1108. xfree(b);
  1109. xfree(c);
  1110. xfree(x);
  1111. xfree(y);
  1112. xfree(z);
  1113. return ret;
  1114. }
  1115. /* eof */