COIN-OR::LEMON - Graph Library

source: glpk-cmake/src/glpluf.h @ 1:c445c931472f

Last change on this file since 1:c445c931472f was 1:c445c931472f, checked in by Alpar Juttner <alpar@…>, 13 years ago

Import glpk-4.45

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