glplpf.c 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979
  1. /* glplpf.c (LP basis factorization, Schur complement version) */
  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 "glplpf.h"
  24. #include "glpenv.h"
  25. #define xfault xerror
  26. #define _GLPLPF_DEBUG 0
  27. /* CAUTION: DO NOT CHANGE THE LIMIT BELOW */
  28. #define M_MAX 100000000 /* = 100*10^6 */
  29. /* maximal order of the basis matrix */
  30. /***********************************************************************
  31. * NAME
  32. *
  33. * lpf_create_it - create LP basis factorization
  34. *
  35. * SYNOPSIS
  36. *
  37. * #include "glplpf.h"
  38. * LPF *lpf_create_it(void);
  39. *
  40. * DESCRIPTION
  41. *
  42. * The routine lpf_create_it creates a program object, which represents
  43. * a factorization of LP basis.
  44. *
  45. * RETURNS
  46. *
  47. * The routine lpf_create_it returns a pointer to the object created. */
  48. LPF *lpf_create_it(void)
  49. { LPF *lpf;
  50. #if _GLPLPF_DEBUG
  51. xprintf("lpf_create_it: warning: debug mode enabled\n");
  52. #endif
  53. lpf = xmalloc(sizeof(LPF));
  54. lpf->valid = 0;
  55. lpf->m0_max = lpf->m0 = 0;
  56. lpf->luf = luf_create_it();
  57. lpf->m = 0;
  58. lpf->B = NULL;
  59. lpf->n_max = 50;
  60. lpf->n = 0;
  61. lpf->R_ptr = lpf->R_len = NULL;
  62. lpf->S_ptr = lpf->S_len = NULL;
  63. lpf->scf = NULL;
  64. lpf->P_row = lpf->P_col = NULL;
  65. lpf->Q_row = lpf->Q_col = NULL;
  66. lpf->v_size = 1000;
  67. lpf->v_ptr = 0;
  68. lpf->v_ind = NULL;
  69. lpf->v_val = NULL;
  70. lpf->work1 = lpf->work2 = NULL;
  71. return lpf;
  72. }
  73. /***********************************************************************
  74. * NAME
  75. *
  76. * lpf_factorize - compute LP basis factorization
  77. *
  78. * SYNOPSIS
  79. *
  80. * #include "glplpf.h"
  81. * int lpf_factorize(LPF *lpf, int m, const int bh[], int (*col)
  82. * (void *info, int j, int ind[], double val[]), void *info);
  83. *
  84. * DESCRIPTION
  85. *
  86. * The routine lpf_factorize computes the factorization of the basis
  87. * matrix B specified by the routine col.
  88. *
  89. * The parameter lpf specified the basis factorization data structure
  90. * created with the routine lpf_create_it.
  91. *
  92. * The parameter m specifies the order of B, m > 0.
  93. *
  94. * The array bh specifies the basis header: bh[j], 1 <= j <= m, is the
  95. * number of j-th column of B in some original matrix. The array bh is
  96. * optional and can be specified as NULL.
  97. *
  98. * The formal routine col specifies the matrix B to be factorized. To
  99. * obtain j-th column of A the routine lpf_factorize calls the routine
  100. * col with the parameter j (1 <= j <= n). In response the routine col
  101. * should store row indices and numerical values of non-zero elements
  102. * of j-th column of B to locations ind[1,...,len] and val[1,...,len],
  103. * respectively, where len is the number of non-zeros in j-th column
  104. * returned on exit. Neither zero nor duplicate elements are allowed.
  105. *
  106. * The parameter info is a transit pointer passed to the routine col.
  107. *
  108. * RETURNS
  109. *
  110. * 0 The factorization has been successfully computed.
  111. *
  112. * LPF_ESING
  113. * The specified matrix is singular within the working precision.
  114. *
  115. * LPF_ECOND
  116. * The specified matrix is ill-conditioned.
  117. *
  118. * For more details see comments to the routine luf_factorize. */
  119. int lpf_factorize(LPF *lpf, int m, const int bh[], int (*col)
  120. (void *info, int j, int ind[], double val[]), void *info)
  121. { int k, ret;
  122. #if _GLPLPF_DEBUG
  123. int i, j, len, *ind;
  124. double *B, *val;
  125. #endif
  126. xassert(bh == bh);
  127. if (m < 1)
  128. xfault("lpf_factorize: m = %d; invalid parameter\n", m);
  129. if (m > M_MAX)
  130. xfault("lpf_factorize: m = %d; matrix too big\n", m);
  131. lpf->m0 = lpf->m = m;
  132. /* invalidate the factorization */
  133. lpf->valid = 0;
  134. /* allocate/reallocate arrays, if necessary */
  135. if (lpf->R_ptr == NULL)
  136. lpf->R_ptr = xcalloc(1+lpf->n_max, sizeof(int));
  137. if (lpf->R_len == NULL)
  138. lpf->R_len = xcalloc(1+lpf->n_max, sizeof(int));
  139. if (lpf->S_ptr == NULL)
  140. lpf->S_ptr = xcalloc(1+lpf->n_max, sizeof(int));
  141. if (lpf->S_len == NULL)
  142. lpf->S_len = xcalloc(1+lpf->n_max, sizeof(int));
  143. if (lpf->scf == NULL)
  144. lpf->scf = scf_create_it(lpf->n_max);
  145. if (lpf->v_ind == NULL)
  146. lpf->v_ind = xcalloc(1+lpf->v_size, sizeof(int));
  147. if (lpf->v_val == NULL)
  148. lpf->v_val = xcalloc(1+lpf->v_size, sizeof(double));
  149. if (lpf->m0_max < m)
  150. { if (lpf->P_row != NULL) xfree(lpf->P_row);
  151. if (lpf->P_col != NULL) xfree(lpf->P_col);
  152. if (lpf->Q_row != NULL) xfree(lpf->Q_row);
  153. if (lpf->Q_col != NULL) xfree(lpf->Q_col);
  154. if (lpf->work1 != NULL) xfree(lpf->work1);
  155. if (lpf->work2 != NULL) xfree(lpf->work2);
  156. lpf->m0_max = m + 100;
  157. lpf->P_row = xcalloc(1+lpf->m0_max+lpf->n_max, sizeof(int));
  158. lpf->P_col = xcalloc(1+lpf->m0_max+lpf->n_max, sizeof(int));
  159. lpf->Q_row = xcalloc(1+lpf->m0_max+lpf->n_max, sizeof(int));
  160. lpf->Q_col = xcalloc(1+lpf->m0_max+lpf->n_max, sizeof(int));
  161. lpf->work1 = xcalloc(1+lpf->m0_max+lpf->n_max, sizeof(double));
  162. lpf->work2 = xcalloc(1+lpf->m0_max+lpf->n_max, sizeof(double));
  163. }
  164. /* try to factorize the basis matrix */
  165. switch (luf_factorize(lpf->luf, m, col, info))
  166. { case 0:
  167. break;
  168. case LUF_ESING:
  169. ret = LPF_ESING;
  170. goto done;
  171. case LUF_ECOND:
  172. ret = LPF_ECOND;
  173. goto done;
  174. default:
  175. xassert(lpf != lpf);
  176. }
  177. /* the basis matrix has been successfully factorized */
  178. lpf->valid = 1;
  179. #if _GLPLPF_DEBUG
  180. /* store the basis matrix for debugging */
  181. if (lpf->B != NULL) xfree(lpf->B);
  182. xassert(m <= 32767);
  183. lpf->B = B = xcalloc(1+m*m, sizeof(double));
  184. ind = xcalloc(1+m, sizeof(int));
  185. val = xcalloc(1+m, sizeof(double));
  186. for (k = 1; k <= m * m; k++)
  187. B[k] = 0.0;
  188. for (j = 1; j <= m; j++)
  189. { len = col(info, j, ind, val);
  190. xassert(0 <= len && len <= m);
  191. for (k = 1; k <= len; k++)
  192. { i = ind[k];
  193. xassert(1 <= i && i <= m);
  194. xassert(B[(i - 1) * m + j] == 0.0);
  195. xassert(val[k] != 0.0);
  196. B[(i - 1) * m + j] = val[k];
  197. }
  198. }
  199. xfree(ind);
  200. xfree(val);
  201. #endif
  202. /* B = B0, so there are no additional rows/columns */
  203. lpf->n = 0;
  204. /* reset the Schur complement factorization */
  205. scf_reset_it(lpf->scf);
  206. /* P := Q := I */
  207. for (k = 1; k <= m; k++)
  208. { lpf->P_row[k] = lpf->P_col[k] = k;
  209. lpf->Q_row[k] = lpf->Q_col[k] = k;
  210. }
  211. /* make all SVA locations free */
  212. lpf->v_ptr = 1;
  213. ret = 0;
  214. done: /* return to the calling program */
  215. return ret;
  216. }
  217. /***********************************************************************
  218. * The routine r_prod computes the product y := y + alpha * R * x,
  219. * where x is a n-vector, alpha is a scalar, y is a m0-vector.
  220. *
  221. * Since matrix R is available by columns, the product is computed as
  222. * a linear combination:
  223. *
  224. * y := y + alpha * (R[1] * x[1] + ... + R[n] * x[n]),
  225. *
  226. * where R[j] is j-th column of R. */
  227. static void r_prod(LPF *lpf, double y[], double a, const double x[])
  228. { int n = lpf->n;
  229. int *R_ptr = lpf->R_ptr;
  230. int *R_len = lpf->R_len;
  231. int *v_ind = lpf->v_ind;
  232. double *v_val = lpf->v_val;
  233. int j, beg, end, ptr;
  234. double t;
  235. for (j = 1; j <= n; j++)
  236. { if (x[j] == 0.0) continue;
  237. /* y := y + alpha * R[j] * x[j] */
  238. t = a * x[j];
  239. beg = R_ptr[j];
  240. end = beg + R_len[j];
  241. for (ptr = beg; ptr < end; ptr++)
  242. y[v_ind[ptr]] += t * v_val[ptr];
  243. }
  244. return;
  245. }
  246. /***********************************************************************
  247. * The routine rt_prod computes the product y := y + alpha * R' * x,
  248. * where R' is a matrix transposed to R, x is a m0-vector, alpha is a
  249. * scalar, y is a n-vector.
  250. *
  251. * Since matrix R is available by columns, the product components are
  252. * computed as inner products:
  253. *
  254. * y[j] := y[j] + alpha * (j-th column of R) * x
  255. *
  256. * for j = 1, 2, ..., n. */
  257. static void rt_prod(LPF *lpf, double y[], double a, const double x[])
  258. { int n = lpf->n;
  259. int *R_ptr = lpf->R_ptr;
  260. int *R_len = lpf->R_len;
  261. int *v_ind = lpf->v_ind;
  262. double *v_val = lpf->v_val;
  263. int j, beg, end, ptr;
  264. double t;
  265. for (j = 1; j <= n; j++)
  266. { /* t := (j-th column of R) * x */
  267. t = 0.0;
  268. beg = R_ptr[j];
  269. end = beg + R_len[j];
  270. for (ptr = beg; ptr < end; ptr++)
  271. t += v_val[ptr] * x[v_ind[ptr]];
  272. /* y[j] := y[j] + alpha * t */
  273. y[j] += a * t;
  274. }
  275. return;
  276. }
  277. /***********************************************************************
  278. * The routine s_prod computes the product y := y + alpha * S * x,
  279. * where x is a m0-vector, alpha is a scalar, y is a n-vector.
  280. *
  281. * Since matrix S is available by rows, the product components are
  282. * computed as inner products:
  283. *
  284. * y[i] = y[i] + alpha * (i-th row of S) * x
  285. *
  286. * for i = 1, 2, ..., n. */
  287. static void s_prod(LPF *lpf, double y[], double a, const double x[])
  288. { int n = lpf->n;
  289. int *S_ptr = lpf->S_ptr;
  290. int *S_len = lpf->S_len;
  291. int *v_ind = lpf->v_ind;
  292. double *v_val = lpf->v_val;
  293. int i, beg, end, ptr;
  294. double t;
  295. for (i = 1; i <= n; i++)
  296. { /* t := (i-th row of S) * x */
  297. t = 0.0;
  298. beg = S_ptr[i];
  299. end = beg + S_len[i];
  300. for (ptr = beg; ptr < end; ptr++)
  301. t += v_val[ptr] * x[v_ind[ptr]];
  302. /* y[i] := y[i] + alpha * t */
  303. y[i] += a * t;
  304. }
  305. return;
  306. }
  307. /***********************************************************************
  308. * The routine st_prod computes the product y := y + alpha * S' * x,
  309. * where S' is a matrix transposed to S, x is a n-vector, alpha is a
  310. * scalar, y is m0-vector.
  311. *
  312. * Since matrix R is available by rows, the product is computed as a
  313. * linear combination:
  314. *
  315. * y := y + alpha * (S'[1] * x[1] + ... + S'[n] * x[n]),
  316. *
  317. * where S'[i] is i-th row of S. */
  318. static void st_prod(LPF *lpf, double y[], double a, const double x[])
  319. { int n = lpf->n;
  320. int *S_ptr = lpf->S_ptr;
  321. int *S_len = lpf->S_len;
  322. int *v_ind = lpf->v_ind;
  323. double *v_val = lpf->v_val;
  324. int i, beg, end, ptr;
  325. double t;
  326. for (i = 1; i <= n; i++)
  327. { if (x[i] == 0.0) continue;
  328. /* y := y + alpha * S'[i] * x[i] */
  329. t = a * x[i];
  330. beg = S_ptr[i];
  331. end = beg + S_len[i];
  332. for (ptr = beg; ptr < end; ptr++)
  333. y[v_ind[ptr]] += t * v_val[ptr];
  334. }
  335. return;
  336. }
  337. #if _GLPLPF_DEBUG
  338. /***********************************************************************
  339. * The routine check_error computes the maximal relative error between
  340. * left- and right-hand sides for the system B * x = b (if tr is zero)
  341. * or B' * x = b (if tr is non-zero), where B' is a matrix transposed
  342. * to B. (This routine is intended for debugging only.) */
  343. static void check_error(LPF *lpf, int tr, const double x[],
  344. const double b[])
  345. { int m = lpf->m;
  346. double *B = lpf->B;
  347. int i, j;
  348. double d, dmax = 0.0, s, t, tmax;
  349. for (i = 1; i <= m; i++)
  350. { s = 0.0;
  351. tmax = 1.0;
  352. for (j = 1; j <= m; j++)
  353. { if (!tr)
  354. t = B[m * (i - 1) + j] * x[j];
  355. else
  356. t = B[m * (j - 1) + i] * x[j];
  357. if (tmax < fabs(t)) tmax = fabs(t);
  358. s += t;
  359. }
  360. d = fabs(s - b[i]) / tmax;
  361. if (dmax < d) dmax = d;
  362. }
  363. if (dmax > 1e-8)
  364. xprintf("%s: dmax = %g; relative error too large\n",
  365. !tr ? "lpf_ftran" : "lpf_btran", dmax);
  366. return;
  367. }
  368. #endif
  369. /***********************************************************************
  370. * NAME
  371. *
  372. * lpf_ftran - perform forward transformation (solve system B*x = b)
  373. *
  374. * SYNOPSIS
  375. *
  376. * #include "glplpf.h"
  377. * void lpf_ftran(LPF *lpf, double x[]);
  378. *
  379. * DESCRIPTION
  380. *
  381. * The routine lpf_ftran performs forward transformation, i.e. solves
  382. * the system B*x = b, where B is the basis matrix, x is the vector of
  383. * unknowns to be computed, b is the vector of right-hand sides.
  384. *
  385. * On entry elements of the vector b should be stored in dense format
  386. * in locations x[1], ..., x[m], where m is the number of rows. On exit
  387. * the routine stores elements of the vector x in the same locations.
  388. *
  389. * BACKGROUND
  390. *
  391. * Solution of the system B * x = b can be obtained by solving the
  392. * following augmented system:
  393. *
  394. * ( B F^) ( x ) ( b )
  395. * ( ) ( ) = ( )
  396. * ( G^ H^) ( y ) ( 0 )
  397. *
  398. * which, using the main equality, can be written as follows:
  399. *
  400. * ( L0 0 ) ( U0 R ) ( x ) ( b )
  401. * P ( ) ( ) Q ( ) = ( )
  402. * ( S I ) ( 0 C ) ( y ) ( 0 )
  403. *
  404. * therefore,
  405. *
  406. * ( x ) ( U0 R )-1 ( L0 0 )-1 ( b )
  407. * ( ) = Q' ( ) ( ) P' ( )
  408. * ( y ) ( 0 C ) ( S I ) ( 0 )
  409. *
  410. * Thus, computing the solution includes the following steps:
  411. *
  412. * 1. Compute
  413. *
  414. * ( f ) ( b )
  415. * ( ) = P' ( )
  416. * ( g ) ( 0 )
  417. *
  418. * 2. Solve the system
  419. *
  420. * ( f1 ) ( L0 0 )-1 ( f ) ( L0 0 ) ( f1 ) ( f )
  421. * ( ) = ( ) ( ) => ( ) ( ) = ( )
  422. * ( g1 ) ( S I ) ( g ) ( S I ) ( g1 ) ( g )
  423. *
  424. * from which it follows that:
  425. *
  426. * { L0 * f1 = f f1 = inv(L0) * f
  427. * { =>
  428. * { S * f1 + g1 = g g1 = g - S * f1
  429. *
  430. * 3. Solve the system
  431. *
  432. * ( f2 ) ( U0 R )-1 ( f1 ) ( U0 R ) ( f2 ) ( f1 )
  433. * ( ) = ( ) ( ) => ( ) ( ) = ( )
  434. * ( g2 ) ( 0 C ) ( g1 ) ( 0 C ) ( g2 ) ( g1 )
  435. *
  436. * from which it follows that:
  437. *
  438. * { U0 * f2 + R * g2 = f1 f2 = inv(U0) * (f1 - R * g2)
  439. * { =>
  440. * { C * g2 = g1 g2 = inv(C) * g1
  441. *
  442. * 4. Compute
  443. *
  444. * ( x ) ( f2 )
  445. * ( ) = Q' ( )
  446. * ( y ) ( g2 ) */
  447. void lpf_ftran(LPF *lpf, double x[])
  448. { int m0 = lpf->m0;
  449. int m = lpf->m;
  450. int n = lpf->n;
  451. int *P_col = lpf->P_col;
  452. int *Q_col = lpf->Q_col;
  453. double *fg = lpf->work1;
  454. double *f = fg;
  455. double *g = fg + m0;
  456. int i, ii;
  457. #if _GLPLPF_DEBUG
  458. double *b;
  459. #endif
  460. if (!lpf->valid)
  461. xfault("lpf_ftran: the factorization is not valid\n");
  462. xassert(0 <= m && m <= m0 + n);
  463. #if _GLPLPF_DEBUG
  464. /* save the right-hand side vector */
  465. b = xcalloc(1+m, sizeof(double));
  466. for (i = 1; i <= m; i++) b[i] = x[i];
  467. #endif
  468. /* (f g) := inv(P) * (b 0) */
  469. for (i = 1; i <= m0 + n; i++)
  470. fg[i] = ((ii = P_col[i]) <= m ? x[ii] : 0.0);
  471. /* f1 := inv(L0) * f */
  472. luf_f_solve(lpf->luf, 0, f);
  473. /* g1 := g - S * f1 */
  474. s_prod(lpf, g, -1.0, f);
  475. /* g2 := inv(C) * g1 */
  476. scf_solve_it(lpf->scf, 0, g);
  477. /* f2 := inv(U0) * (f1 - R * g2) */
  478. r_prod(lpf, f, -1.0, g);
  479. luf_v_solve(lpf->luf, 0, f);
  480. /* (x y) := inv(Q) * (f2 g2) */
  481. for (i = 1; i <= m; i++)
  482. x[i] = fg[Q_col[i]];
  483. #if _GLPLPF_DEBUG
  484. /* check relative error in solution */
  485. check_error(lpf, 0, x, b);
  486. xfree(b);
  487. #endif
  488. return;
  489. }
  490. /***********************************************************************
  491. * NAME
  492. *
  493. * lpf_btran - perform backward transformation (solve system B'*x = b)
  494. *
  495. * SYNOPSIS
  496. *
  497. * #include "glplpf.h"
  498. * void lpf_btran(LPF *lpf, double x[]);
  499. *
  500. * DESCRIPTION
  501. *
  502. * The routine lpf_btran performs backward transformation, i.e. solves
  503. * the system B'*x = b, where B' is a matrix transposed to the basis
  504. * matrix B, x is the vector of unknowns to be computed, b is the vector
  505. * of right-hand sides.
  506. *
  507. * On entry elements of the vector b should be stored in dense format
  508. * in locations x[1], ..., x[m], where m is the number of rows. On exit
  509. * the routine stores elements of the vector x in the same locations.
  510. *
  511. * BACKGROUND
  512. *
  513. * Solution of the system B' * x = b, where B' is a matrix transposed
  514. * to B, can be obtained by solving the following augmented system:
  515. *
  516. * ( B F^)T ( x ) ( b )
  517. * ( ) ( ) = ( )
  518. * ( G^ H^) ( y ) ( 0 )
  519. *
  520. * which, using the main equality, can be written as follows:
  521. *
  522. * T ( U0 R )T ( L0 0 )T T ( x ) ( b )
  523. * Q ( ) ( ) P ( ) = ( )
  524. * ( 0 C ) ( S I ) ( y ) ( 0 )
  525. *
  526. * or, equivalently, as follows:
  527. *
  528. * ( U'0 0 ) ( L'0 S') ( x ) ( b )
  529. * Q' ( ) ( ) P' ( ) = ( )
  530. * ( R' C') ( 0 I ) ( y ) ( 0 )
  531. *
  532. * therefore,
  533. *
  534. * ( x ) ( L'0 S')-1 ( U'0 0 )-1 ( b )
  535. * ( ) = P ( ) ( ) Q ( )
  536. * ( y ) ( 0 I ) ( R' C') ( 0 )
  537. *
  538. * Thus, computing the solution includes the following steps:
  539. *
  540. * 1. Compute
  541. *
  542. * ( f ) ( b )
  543. * ( ) = Q ( )
  544. * ( g ) ( 0 )
  545. *
  546. * 2. Solve the system
  547. *
  548. * ( f1 ) ( U'0 0 )-1 ( f ) ( U'0 0 ) ( f1 ) ( f )
  549. * ( ) = ( ) ( ) => ( ) ( ) = ( )
  550. * ( g1 ) ( R' C') ( g ) ( R' C') ( g1 ) ( g )
  551. *
  552. * from which it follows that:
  553. *
  554. * { U'0 * f1 = f f1 = inv(U'0) * f
  555. * { =>
  556. * { R' * f1 + C' * g1 = g g1 = inv(C') * (g - R' * f1)
  557. *
  558. * 3. Solve the system
  559. *
  560. * ( f2 ) ( L'0 S')-1 ( f1 ) ( L'0 S') ( f2 ) ( f1 )
  561. * ( ) = ( ) ( ) => ( ) ( ) = ( )
  562. * ( g2 ) ( 0 I ) ( g1 ) ( 0 I ) ( g2 ) ( g1 )
  563. *
  564. * from which it follows that:
  565. *
  566. * { L'0 * f2 + S' * g2 = f1
  567. * { => f2 = inv(L'0) * ( f1 - S' * g2)
  568. * { g2 = g1
  569. *
  570. * 4. Compute
  571. *
  572. * ( x ) ( f2 )
  573. * ( ) = P ( )
  574. * ( y ) ( g2 ) */
  575. void lpf_btran(LPF *lpf, double x[])
  576. { int m0 = lpf->m0;
  577. int m = lpf->m;
  578. int n = lpf->n;
  579. int *P_row = lpf->P_row;
  580. int *Q_row = lpf->Q_row;
  581. double *fg = lpf->work1;
  582. double *f = fg;
  583. double *g = fg + m0;
  584. int i, ii;
  585. #if _GLPLPF_DEBUG
  586. double *b;
  587. #endif
  588. if (!lpf->valid)
  589. xfault("lpf_btran: the factorization is not valid\n");
  590. xassert(0 <= m && m <= m0 + n);
  591. #if _GLPLPF_DEBUG
  592. /* save the right-hand side vector */
  593. b = xcalloc(1+m, sizeof(double));
  594. for (i = 1; i <= m; i++) b[i] = x[i];
  595. #endif
  596. /* (f g) := Q * (b 0) */
  597. for (i = 1; i <= m0 + n; i++)
  598. fg[i] = ((ii = Q_row[i]) <= m ? x[ii] : 0.0);
  599. /* f1 := inv(U'0) * f */
  600. luf_v_solve(lpf->luf, 1, f);
  601. /* g1 := inv(C') * (g - R' * f1) */
  602. rt_prod(lpf, g, -1.0, f);
  603. scf_solve_it(lpf->scf, 1, g);
  604. /* g2 := g1 */
  605. g = g;
  606. /* f2 := inv(L'0) * (f1 - S' * g2) */
  607. st_prod(lpf, f, -1.0, g);
  608. luf_f_solve(lpf->luf, 1, f);
  609. /* (x y) := P * (f2 g2) */
  610. for (i = 1; i <= m; i++)
  611. x[i] = fg[P_row[i]];
  612. #if _GLPLPF_DEBUG
  613. /* check relative error in solution */
  614. check_error(lpf, 1, x, b);
  615. xfree(b);
  616. #endif
  617. return;
  618. }
  619. /***********************************************************************
  620. * The routine enlarge_sva enlarges the Sparse Vector Area to new_size
  621. * locations by reallocating the arrays v_ind and v_val. */
  622. static void enlarge_sva(LPF *lpf, int new_size)
  623. { int v_size = lpf->v_size;
  624. int used = lpf->v_ptr - 1;
  625. int *v_ind = lpf->v_ind;
  626. double *v_val = lpf->v_val;
  627. xassert(v_size < new_size);
  628. while (v_size < new_size) v_size += v_size;
  629. lpf->v_size = v_size;
  630. lpf->v_ind = xcalloc(1+v_size, sizeof(int));
  631. lpf->v_val = xcalloc(1+v_size, sizeof(double));
  632. xassert(used >= 0);
  633. memcpy(&lpf->v_ind[1], &v_ind[1], used * sizeof(int));
  634. memcpy(&lpf->v_val[1], &v_val[1], used * sizeof(double));
  635. xfree(v_ind);
  636. xfree(v_val);
  637. return;
  638. }
  639. /***********************************************************************
  640. * NAME
  641. *
  642. * lpf_update_it - update LP basis factorization
  643. *
  644. * SYNOPSIS
  645. *
  646. * #include "glplpf.h"
  647. * int lpf_update_it(LPF *lpf, int j, int bh, int len, const int ind[],
  648. * const double val[]);
  649. *
  650. * DESCRIPTION
  651. *
  652. * The routine lpf_update_it updates the factorization of the basis
  653. * matrix B after replacing its j-th column by a new vector.
  654. *
  655. * The parameter j specifies the number of column of B, which has been
  656. * replaced, 1 <= j <= m, where m is the order of B.
  657. *
  658. * The parameter bh specifies the basis header entry for the new column
  659. * of B, which is the number of the new column in some original matrix.
  660. * This parameter is optional and can be specified as 0.
  661. *
  662. * Row indices and numerical values of non-zero elements of the new
  663. * column of B should be placed in locations ind[1], ..., ind[len] and
  664. * val[1], ..., val[len], resp., where len is the number of non-zeros
  665. * in the column. Neither zero nor duplicate elements are allowed.
  666. *
  667. * RETURNS
  668. *
  669. * 0 The factorization has been successfully updated.
  670. *
  671. * LPF_ESING
  672. * New basis B is singular within the working precision.
  673. *
  674. * LPF_ELIMIT
  675. * Maximal number of additional rows and columns has been reached.
  676. *
  677. * BACKGROUND
  678. *
  679. * Let j-th column of the current basis matrix B have to be replaced by
  680. * a new column a. This replacement is equivalent to removing the old
  681. * j-th column by fixing it at zero and introducing the new column as
  682. * follows:
  683. *
  684. * ( B F^| a )
  685. * ( B F^) ( | )
  686. * ( ) ---> ( G^ H^| 0 )
  687. * ( G^ H^) (-------+---)
  688. * ( e'j 0 | 0 )
  689. *
  690. * where ej is a unit vector with 1 in j-th position which used to fix
  691. * the old j-th column of B (at zero). Then using the main equality we
  692. * have:
  693. *
  694. * ( B F^| a ) ( B0 F | f )
  695. * ( | ) ( P 0 ) ( | ) ( Q 0 )
  696. * ( G^ H^| 0 ) = ( ) ( G H | g ) ( ) =
  697. * (-------+---) ( 0 1 ) (-------+---) ( 0 1 )
  698. * ( e'j 0 | 0 ) ( v' w'| 0 )
  699. *
  700. * [ ( B0 F )| ( f ) ] [ ( B0 F ) | ( f ) ]
  701. * [ P ( )| P ( ) ] ( Q 0 ) [ P ( ) Q| P ( ) ]
  702. * = [ ( G H )| ( g ) ] ( ) = [ ( G H ) | ( g ) ]
  703. * [------------+-------- ] ( 0 1 ) [-------------+---------]
  704. * [ ( v' w')| 0 ] [ ( v' w') Q| 0 ]
  705. *
  706. * where:
  707. *
  708. * ( a ) ( f ) ( f ) ( a )
  709. * ( ) = P ( ) => ( ) = P' * ( )
  710. * ( 0 ) ( g ) ( g ) ( 0 )
  711. *
  712. * ( ej ) ( v ) ( v ) ( ej )
  713. * ( e'j 0 ) = ( v' w' ) Q => ( ) = Q' ( ) => ( ) = Q ( )
  714. * ( 0 ) ( w ) ( w ) ( 0 )
  715. *
  716. * On the other hand:
  717. *
  718. * ( B0| F f )
  719. * ( P 0 ) (---+------) ( Q 0 ) ( B0 new F )
  720. * ( ) ( G | H g ) ( ) = new P ( ) new Q
  721. * ( 0 1 ) ( | ) ( 0 1 ) ( new G new H )
  722. * ( v'| w' 0 )
  723. *
  724. * where:
  725. * ( G ) ( H g )
  726. * new F = ( F f ), new G = ( ), new H = ( ),
  727. * ( v') ( w' 0 )
  728. *
  729. * ( P 0 ) ( Q 0 )
  730. * new P = ( ) , new Q = ( ) .
  731. * ( 0 1 ) ( 0 1 )
  732. *
  733. * The factorization structure for the new augmented matrix remains the
  734. * same, therefore:
  735. *
  736. * ( B0 new F ) ( L0 0 ) ( U0 new R )
  737. * new P ( ) new Q = ( ) ( )
  738. * ( new G new H ) ( new S I ) ( 0 new C )
  739. *
  740. * where:
  741. *
  742. * new F = L0 * new R =>
  743. *
  744. * new R = inv(L0) * new F = inv(L0) * (F f) = ( R inv(L0)*f )
  745. *
  746. * new G = new S * U0 =>
  747. *
  748. * ( G ) ( S )
  749. * new S = new G * inv(U0) = ( ) * inv(U0) = ( )
  750. * ( v') ( v'*inv(U0) )
  751. *
  752. * new H = new S * new R + new C =>
  753. *
  754. * new C = new H - new S * new R =
  755. *
  756. * ( H g ) ( S )
  757. * = ( ) - ( ) * ( R inv(L0)*f ) =
  758. * ( w' 0 ) ( v'*inv(U0) )
  759. *
  760. * ( H - S*R g - S*inv(L0)*f ) ( C x )
  761. * = ( ) = ( )
  762. * ( w'- v'*inv(U0)*R -v'*inv(U0)*inv(L0)*f) ( y' z )
  763. *
  764. * Note that new C is resulted by expanding old C with new column x,
  765. * row y', and diagonal element z, where:
  766. *
  767. * x = g - S * inv(L0) * f = g - S * (new column of R)
  768. *
  769. * y = w - R'* inv(U'0)* v = w - R'* (new row of S)
  770. *
  771. * z = - (new row of S) * (new column of R)
  772. *
  773. * Finally, to replace old B by new B we have to permute j-th and last
  774. * (just added) columns of the matrix
  775. *
  776. * ( B F^| a )
  777. * ( | )
  778. * ( G^ H^| 0 )
  779. * (-------+---)
  780. * ( e'j 0 | 0 )
  781. *
  782. * and to keep the main equality do the same for matrix Q. */
  783. int lpf_update_it(LPF *lpf, int j, int bh, int len, const int ind[],
  784. const double val[])
  785. { int m0 = lpf->m0;
  786. int m = lpf->m;
  787. #if _GLPLPF_DEBUG
  788. double *B = lpf->B;
  789. #endif
  790. int n = lpf->n;
  791. int *R_ptr = lpf->R_ptr;
  792. int *R_len = lpf->R_len;
  793. int *S_ptr = lpf->S_ptr;
  794. int *S_len = lpf->S_len;
  795. int *P_row = lpf->P_row;
  796. int *P_col = lpf->P_col;
  797. int *Q_row = lpf->Q_row;
  798. int *Q_col = lpf->Q_col;
  799. int v_ptr = lpf->v_ptr;
  800. int *v_ind = lpf->v_ind;
  801. double *v_val = lpf->v_val;
  802. double *a = lpf->work2; /* new column */
  803. double *fg = lpf->work1, *f = fg, *g = fg + m0;
  804. double *vw = lpf->work2, *v = vw, *w = vw + m0;
  805. double *x = g, *y = w, z;
  806. int i, ii, k, ret;
  807. xassert(bh == bh);
  808. if (!lpf->valid)
  809. xfault("lpf_update_it: the factorization is not valid\n");
  810. if (!(1 <= j && j <= m))
  811. xfault("lpf_update_it: j = %d; column number out of range\n",
  812. j);
  813. xassert(0 <= m && m <= m0 + n);
  814. /* check if the basis factorization can be expanded */
  815. if (n == lpf->n_max)
  816. { lpf->valid = 0;
  817. ret = LPF_ELIMIT;
  818. goto done;
  819. }
  820. /* convert new j-th column of B to dense format */
  821. for (i = 1; i <= m; i++)
  822. a[i] = 0.0;
  823. for (k = 1; k <= len; k++)
  824. { i = ind[k];
  825. if (!(1 <= i && i <= m))
  826. xfault("lpf_update_it: ind[%d] = %d; row number out of rang"
  827. "e\n", k, i);
  828. if (a[i] != 0.0)
  829. xfault("lpf_update_it: ind[%d] = %d; duplicate row index no"
  830. "t allowed\n", k, i);
  831. if (val[k] == 0.0)
  832. xfault("lpf_update_it: val[%d] = %g; zero element not allow"
  833. "ed\n", k, val[k]);
  834. a[i] = val[k];
  835. }
  836. #if _GLPLPF_DEBUG
  837. /* change column in the basis matrix for debugging */
  838. for (i = 1; i <= m; i++)
  839. B[(i - 1) * m + j] = a[i];
  840. #endif
  841. /* (f g) := inv(P) * (a 0) */
  842. for (i = 1; i <= m0+n; i++)
  843. fg[i] = ((ii = P_col[i]) <= m ? a[ii] : 0.0);
  844. /* (v w) := Q * (ej 0) */
  845. for (i = 1; i <= m0+n; i++) vw[i] = 0.0;
  846. vw[Q_col[j]] = 1.0;
  847. /* f1 := inv(L0) * f (new column of R) */
  848. luf_f_solve(lpf->luf, 0, f);
  849. /* v1 := inv(U'0) * v (new row of S) */
  850. luf_v_solve(lpf->luf, 1, v);
  851. /* we need at most 2 * m0 available locations in the SVA to store
  852. new column of matrix R and new row of matrix S */
  853. if (lpf->v_size < v_ptr + m0 + m0)
  854. { enlarge_sva(lpf, v_ptr + m0 + m0);
  855. v_ind = lpf->v_ind;
  856. v_val = lpf->v_val;
  857. }
  858. /* store new column of R */
  859. R_ptr[n+1] = v_ptr;
  860. for (i = 1; i <= m0; i++)
  861. { if (f[i] != 0.0)
  862. v_ind[v_ptr] = i, v_val[v_ptr] = f[i], v_ptr++;
  863. }
  864. R_len[n+1] = v_ptr - lpf->v_ptr;
  865. lpf->v_ptr = v_ptr;
  866. /* store new row of S */
  867. S_ptr[n+1] = v_ptr;
  868. for (i = 1; i <= m0; i++)
  869. { if (v[i] != 0.0)
  870. v_ind[v_ptr] = i, v_val[v_ptr] = v[i], v_ptr++;
  871. }
  872. S_len[n+1] = v_ptr - lpf->v_ptr;
  873. lpf->v_ptr = v_ptr;
  874. /* x := g - S * f1 (new column of C) */
  875. s_prod(lpf, x, -1.0, f);
  876. /* y := w - R' * v1 (new row of C) */
  877. rt_prod(lpf, y, -1.0, v);
  878. /* z := - v1 * f1 (new diagonal element of C) */
  879. z = 0.0;
  880. for (i = 1; i <= m0; i++) z -= v[i] * f[i];
  881. /* update factorization of new matrix C */
  882. switch (scf_update_exp(lpf->scf, x, y, z))
  883. { case 0:
  884. break;
  885. case SCF_ESING:
  886. lpf->valid = 0;
  887. ret = LPF_ESING;
  888. goto done;
  889. case SCF_ELIMIT:
  890. xassert(lpf != lpf);
  891. default:
  892. xassert(lpf != lpf);
  893. }
  894. /* expand matrix P */
  895. P_row[m0+n+1] = P_col[m0+n+1] = m0+n+1;
  896. /* expand matrix Q */
  897. Q_row[m0+n+1] = Q_col[m0+n+1] = m0+n+1;
  898. /* permute j-th and last (just added) column of matrix Q */
  899. i = Q_col[j], ii = Q_col[m0+n+1];
  900. Q_row[i] = m0+n+1, Q_col[m0+n+1] = i;
  901. Q_row[ii] = j, Q_col[j] = ii;
  902. /* increase the number of additional rows and columns */
  903. lpf->n++;
  904. xassert(lpf->n <= lpf->n_max);
  905. /* the factorization has been successfully updated */
  906. ret = 0;
  907. done: /* return to the calling program */
  908. return ret;
  909. }
  910. /***********************************************************************
  911. * NAME
  912. *
  913. * lpf_delete_it - delete LP basis factorization
  914. *
  915. * SYNOPSIS
  916. *
  917. * #include "glplpf.h"
  918. * void lpf_delete_it(LPF *lpf)
  919. *
  920. * DESCRIPTION
  921. *
  922. * The routine lpf_delete_it deletes LP basis factorization specified
  923. * by the parameter lpf and frees all memory allocated to this program
  924. * object. */
  925. void lpf_delete_it(LPF *lpf)
  926. { luf_delete_it(lpf->luf);
  927. #if _GLPLPF_DEBUG
  928. if (lpf->B != NULL) xfree(lpf->B);
  929. #else
  930. xassert(lpf->B == NULL);
  931. #endif
  932. if (lpf->R_ptr != NULL) xfree(lpf->R_ptr);
  933. if (lpf->R_len != NULL) xfree(lpf->R_len);
  934. if (lpf->S_ptr != NULL) xfree(lpf->S_ptr);
  935. if (lpf->S_len != NULL) xfree(lpf->S_len);
  936. if (lpf->scf != NULL) scf_delete_it(lpf->scf);
  937. if (lpf->P_row != NULL) xfree(lpf->P_row);
  938. if (lpf->P_col != NULL) xfree(lpf->P_col);
  939. if (lpf->Q_row != NULL) xfree(lpf->Q_row);
  940. if (lpf->Q_col != NULL) xfree(lpf->Q_col);
  941. if (lpf->v_ind != NULL) xfree(lpf->v_ind);
  942. if (lpf->v_val != NULL) xfree(lpf->v_val);
  943. if (lpf->work1 != NULL) xfree(lpf->work1);
  944. if (lpf->work2 != NULL) xfree(lpf->work2);
  945. xfree(lpf);
  946. return;
  947. }
  948. /* eof */