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.

1097 lines
33 KiB

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