glpluf.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  1. /* glpluf.h (LU-factorization) */
  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. #ifndef GLPLUF_H
  24. #define GLPLUF_H
  25. /***********************************************************************
  26. * The structure LUF defines LU-factorization of a square matrix A and
  27. * is the following quartet:
  28. *
  29. * [A] = (F, V, P, Q), (1)
  30. *
  31. * where F and V are such matrices that
  32. *
  33. * A = F * V, (2)
  34. *
  35. * and P and Q are such permutation matrices that the matrix
  36. *
  37. * L = P * F * inv(P) (3)
  38. *
  39. * is lower triangular with unity diagonal, and the matrix
  40. *
  41. * U = P * V * Q (4)
  42. *
  43. * is upper triangular. All the matrices have the order n.
  44. *
  45. * Matrices F and V are stored in row- and column-wise sparse format
  46. * as row and column linked lists of non-zero elements. Unity elements
  47. * on the main diagonal of matrix F are not stored. Pivot elements of
  48. * matrix V (which correspond to diagonal elements of matrix U) are
  49. * stored separately in an ordinary array.
  50. *
  51. * Permutation matrices P and Q are stored in ordinary arrays in both
  52. * row- and column-like formats.
  53. *
  54. * Matrices L and U are completely defined by matrices F, V, P, and Q
  55. * and therefore not stored explicitly.
  56. *
  57. * The factorization (1)-(4) is a version of LU-factorization. Indeed,
  58. * from (3) and (4) it follows that:
  59. *
  60. * F = inv(P) * L * P,
  61. *
  62. * U = inv(P) * U * inv(Q),
  63. *
  64. * and substitution into (2) leads to:
  65. *
  66. * A = F * V = inv(P) * L * U * inv(Q).
  67. *
  68. * For more details see the program documentation. */
  69. typedef struct LUF LUF;
  70. struct LUF
  71. { /* LU-factorization of a square matrix */
  72. int n_max;
  73. /* maximal value of n (increased automatically, if necessary) */
  74. int n;
  75. /* the order of matrices A, F, V, P, Q */
  76. int valid;
  77. /* the factorization is valid only if this flag is set */
  78. /*--------------------------------------------------------------*/
  79. /* matrix F in row-wise format */
  80. int *fr_ptr; /* int fr_ptr[1+n_max]; */
  81. /* fr_ptr[i], i = 1,...,n, is a pointer to the first element of
  82. i-th row in SVA */
  83. int *fr_len; /* int fr_len[1+n_max]; */
  84. /* fr_len[i], i = 1,...,n, is the number of elements in i-th row
  85. (except unity diagonal element) */
  86. /*--------------------------------------------------------------*/
  87. /* matrix F in column-wise format */
  88. int *fc_ptr; /* int fc_ptr[1+n_max]; */
  89. /* fc_ptr[j], j = 1,...,n, is a pointer to the first element of
  90. j-th column in SVA */
  91. int *fc_len; /* int fc_len[1+n_max]; */
  92. /* fc_len[j], j = 1,...,n, is the number of elements in j-th
  93. column (except unity diagonal element) */
  94. /*--------------------------------------------------------------*/
  95. /* matrix V in row-wise format */
  96. int *vr_ptr; /* int vr_ptr[1+n_max]; */
  97. /* vr_ptr[i], i = 1,...,n, is a pointer to the first element of
  98. i-th row in SVA */
  99. int *vr_len; /* int vr_len[1+n_max]; */
  100. /* vr_len[i], i = 1,...,n, is the number of elements in i-th row
  101. (except pivot element) */
  102. int *vr_cap; /* int vr_cap[1+n_max]; */
  103. /* vr_cap[i], i = 1,...,n, is the capacity of i-th row, i.e.
  104. maximal number of elements which can be stored in the row
  105. without relocating it, vr_cap[i] >= vr_len[i] */
  106. double *vr_piv; /* double vr_piv[1+n_max]; */
  107. /* vr_piv[p], p = 1,...,n, is the pivot element v[p,q] which
  108. corresponds to a diagonal element of matrix U = P*V*Q */
  109. /*--------------------------------------------------------------*/
  110. /* matrix V in column-wise format */
  111. int *vc_ptr; /* int vc_ptr[1+n_max]; */
  112. /* vc_ptr[j], j = 1,...,n, is a pointer to the first element of
  113. j-th column in SVA */
  114. int *vc_len; /* int vc_len[1+n_max]; */
  115. /* vc_len[j], j = 1,...,n, is the number of elements in j-th
  116. column (except pivot element) */
  117. int *vc_cap; /* int vc_cap[1+n_max]; */
  118. /* vc_cap[j], j = 1,...,n, is the capacity of j-th column, i.e.
  119. maximal number of elements which can be stored in the column
  120. without relocating it, vc_cap[j] >= vc_len[j] */
  121. /*--------------------------------------------------------------*/
  122. /* matrix P */
  123. int *pp_row; /* int pp_row[1+n_max]; */
  124. /* pp_row[i] = j means that P[i,j] = 1 */
  125. int *pp_col; /* int pp_col[1+n_max]; */
  126. /* pp_col[j] = i means that P[i,j] = 1 */
  127. /* if i-th row or column of matrix F is i'-th row or column of
  128. matrix L, or if i-th row of matrix V is i'-th row of matrix U,
  129. then pp_row[i'] = i and pp_col[i] = i' */
  130. /*--------------------------------------------------------------*/
  131. /* matrix Q */
  132. int *qq_row; /* int qq_row[1+n_max]; */
  133. /* qq_row[i] = j means that Q[i,j] = 1 */
  134. int *qq_col; /* int qq_col[1+n_max]; */
  135. /* qq_col[j] = i means that Q[i,j] = 1 */
  136. /* if j-th column of matrix V is j'-th column of matrix U, then
  137. qq_row[j] = j' and qq_col[j'] = j */
  138. /*--------------------------------------------------------------*/
  139. /* the Sparse Vector Area (SVA) is a set of locations used to
  140. store sparse vectors representing rows and columns of matrices
  141. F and V; each location is a doublet (ind, val), where ind is
  142. an index, and val is a numerical value of a sparse vector
  143. element; in the whole each sparse vector is a set of adjacent
  144. locations defined by a pointer to the first element and the
  145. number of elements; these pointer and number are stored in the
  146. corresponding matrix data structure (see above); the left part
  147. of SVA is used to store rows and columns of matrix V, and its
  148. right part is used to store rows and columns of matrix F; the
  149. middle part of SVA contains free (unused) locations */
  150. int sv_size;
  151. /* the size of SVA, in locations; all locations are numbered by
  152. integers 1, ..., n, and location 0 is not used; if necessary,
  153. the SVA size is automatically increased */
  154. int sv_beg, sv_end;
  155. /* SVA partitioning pointers:
  156. locations from 1 to sv_beg-1 belong to the left part
  157. locations from sv_beg to sv_end-1 belong to the middle part
  158. locations from sv_end to sv_size belong to the right part
  159. the size of the middle part is (sv_end - sv_beg) */
  160. int *sv_ind; /* sv_ind[1+sv_size]; */
  161. /* sv_ind[k], 1 <= k <= sv_size, is the index field of k-th
  162. location */
  163. double *sv_val; /* sv_val[1+sv_size]; */
  164. /* sv_val[k], 1 <= k <= sv_size, is the value field of k-th
  165. location */
  166. /*--------------------------------------------------------------*/
  167. /* in order to efficiently defragment the left part of SVA there
  168. is a doubly linked list of rows and columns of matrix V, where
  169. rows are numbered by 1, ..., n, while columns are numbered by
  170. n+1, ..., n+n, that allows uniquely identifying each row and
  171. column of V by only one integer; in this list rows and columns
  172. are ordered by ascending their pointers vr_ptr and vc_ptr */
  173. int sv_head;
  174. /* the number of leftmost row/column */
  175. int sv_tail;
  176. /* the number of rightmost row/column */
  177. int *sv_prev; /* int sv_prev[1+n_max+n_max]; */
  178. /* sv_prev[k], k = 1,...,n+n, is the number of a row/column which
  179. precedes k-th row/column */
  180. int *sv_next; /* int sv_next[1+n_max+n_max]; */
  181. /* sv_next[k], k = 1,...,n+n, is the number of a row/column which
  182. succedes k-th row/column */
  183. /*--------------------------------------------------------------*/
  184. /* working segment (used only during factorization) */
  185. double *vr_max; /* int vr_max[1+n_max]; */
  186. /* vr_max[i], 1 <= i <= n, is used only if i-th row of matrix V
  187. is active (i.e. belongs to the active submatrix), and is the
  188. largest magnitude of elements in i-th row; if vr_max[i] < 0,
  189. the largest magnitude is not known yet and should be computed
  190. by the pivoting routine */
  191. /*--------------------------------------------------------------*/
  192. /* in order to efficiently implement Markowitz strategy and Duff
  193. search technique there are two families {R[0], R[1], ..., R[n]}
  194. and {C[0], C[1], ..., C[n]}; member R[k] is the set of active
  195. rows of matrix V, which have k non-zeros, and member C[k] is
  196. the set of active columns of V, which have k non-zeros in the
  197. active submatrix (i.e. in the active rows); each set R[k] and
  198. C[k] is implemented as a separate doubly linked list */
  199. int *rs_head; /* int rs_head[1+n_max]; */
  200. /* rs_head[k], 0 <= k <= n, is the number of first active row,
  201. which has k non-zeros */
  202. int *rs_prev; /* int rs_prev[1+n_max]; */
  203. /* rs_prev[i], 1 <= i <= n, is the number of previous row, which
  204. has the same number of non-zeros as i-th row */
  205. int *rs_next; /* int rs_next[1+n_max]; */
  206. /* rs_next[i], 1 <= i <= n, is the number of next row, which has
  207. the same number of non-zeros as i-th row */
  208. int *cs_head; /* int cs_head[1+n_max]; */
  209. /* cs_head[k], 0 <= k <= n, is the number of first active column,
  210. which has k non-zeros (in the active rows) */
  211. int *cs_prev; /* int cs_prev[1+n_max]; */
  212. /* cs_prev[j], 1 <= j <= n, is the number of previous column,
  213. which has the same number of non-zeros (in the active rows) as
  214. j-th column */
  215. int *cs_next; /* int cs_next[1+n_max]; */
  216. /* cs_next[j], 1 <= j <= n, is the number of next column, which
  217. has the same number of non-zeros (in the active rows) as j-th
  218. column */
  219. /* (end of working segment) */
  220. /*--------------------------------------------------------------*/
  221. /* working arrays */
  222. int *flag; /* int flag[1+n_max]; */
  223. /* integer working array */
  224. double *work; /* double work[1+n_max]; */
  225. /* floating-point working array */
  226. /*--------------------------------------------------------------*/
  227. /* control parameters */
  228. int new_sva;
  229. /* new required size of the sparse vector area, in locations; set
  230. automatically by the factorizing routine */
  231. double piv_tol;
  232. /* threshold pivoting tolerance, 0 < piv_tol < 1; element v[i,j]
  233. of the active submatrix fits to be pivot if it satisfies to the
  234. stability criterion |v[i,j]| >= piv_tol * max |v[i,*]|, i.e. if
  235. it is not very small in the magnitude among other elements in
  236. the same row; decreasing this parameter gives better sparsity
  237. at the expense of numerical accuracy and vice versa */
  238. int piv_lim;
  239. /* maximal allowable number of pivot candidates to be considered;
  240. if piv_lim pivot candidates have been considered, the pivoting
  241. routine terminates the search with the best candidate found */
  242. int suhl;
  243. /* if this flag is set, the pivoting routine applies a heuristic
  244. proposed by Uwe Suhl: if a column of the active submatrix has
  245. no eligible pivot candidates (i.e. all its elements do not
  246. satisfy to the stability criterion), the routine excludes it
  247. from futher consideration until it becomes column singleton;
  248. in many cases this allows reducing the time needed for pivot
  249. searching */
  250. double eps_tol;
  251. /* epsilon tolerance; each element of the active submatrix, whose
  252. magnitude is less than eps_tol, is replaced by exact zero */
  253. double max_gro;
  254. /* maximal allowable growth of elements of matrix V during all
  255. the factorization process; if on some eliminaion step the ratio
  256. big_v / max_a (see below) becomes greater than max_gro, matrix
  257. A is considered as ill-conditioned (assuming that the pivoting
  258. tolerance piv_tol has an appropriate value) */
  259. /*--------------------------------------------------------------*/
  260. /* some statistics */
  261. int nnz_a;
  262. /* the number of non-zeros in matrix A */
  263. int nnz_f;
  264. /* the number of non-zeros in matrix F (except diagonal elements,
  265. which are not stored) */
  266. int nnz_v;
  267. /* the number of non-zeros in matrix V (except its pivot elements,
  268. which are stored in a separate array) */
  269. double max_a;
  270. /* the largest magnitude of elements of matrix A */
  271. double big_v;
  272. /* the largest magnitude of elements of matrix V appeared in the
  273. active submatrix during all the factorization process */
  274. int rank;
  275. /* estimated rank of matrix A */
  276. };
  277. /* return codes: */
  278. #define LUF_ESING 1 /* singular matrix */
  279. #define LUF_ECOND 2 /* ill-conditioned matrix */
  280. #define luf_create_it _glp_luf_create_it
  281. LUF *luf_create_it(void);
  282. /* create LU-factorization */
  283. #define luf_defrag_sva _glp_luf_defrag_sva
  284. void luf_defrag_sva(LUF *luf);
  285. /* defragment the sparse vector area */
  286. #define luf_enlarge_row _glp_luf_enlarge_row
  287. int luf_enlarge_row(LUF *luf, int i, int cap);
  288. /* enlarge row capacity */
  289. #define luf_enlarge_col _glp_luf_enlarge_col
  290. int luf_enlarge_col(LUF *luf, int j, int cap);
  291. /* enlarge column capacity */
  292. #define luf_factorize _glp_luf_factorize
  293. int luf_factorize(LUF *luf, int n, int (*col)(void *info, int j,
  294. int ind[], double val[]), void *info);
  295. /* compute LU-factorization */
  296. #define luf_f_solve _glp_luf_f_solve
  297. void luf_f_solve(LUF *luf, int tr, double x[]);
  298. /* solve system F*x = b or F'*x = b */
  299. #define luf_v_solve _glp_luf_v_solve
  300. void luf_v_solve(LUF *luf, int tr, double x[]);
  301. /* solve system V*x = b or V'*x = b */
  302. #define luf_a_solve _glp_luf_a_solve
  303. void luf_a_solve(LUF *luf, int tr, double x[]);
  304. /* solve system A*x = b or A'*x = b */
  305. #define luf_delete_it _glp_luf_delete_it
  306. void luf_delete_it(LUF *luf);
  307. /* delete LU-factorization */
  308. #endif
  309. /* eof */