1 /* glplpf.c (LP basis factorization, Schur complement version) */
3 /***********************************************************************
4 * This code is part of GLPK (GNU Linear Programming Kit).
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>.
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.
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.
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 ***********************************************************************/
29 #define _GLPLPF_DEBUG 0
31 /* CAUTION: DO NOT CHANGE THE LIMIT BELOW */
33 #define M_MAX 100000000 /* = 100*10^6 */
34 /* maximal order of the basis matrix */
36 /***********************************************************************
39 * lpf_create_it - create LP basis factorization
44 * LPF *lpf_create_it(void);
48 * The routine lpf_create_it creates a program object, which represents
49 * a factorization of LP basis.
53 * The routine lpf_create_it returns a pointer to the object created. */
55 LPF *lpf_create_it(void)
58 xprintf("lpf_create_it: warning: debug mode enabled\n");
60 lpf = xmalloc(sizeof(LPF));
62 lpf->m0_max = lpf->m0 = 0;
63 lpf->luf = luf_create_it();
68 lpf->R_ptr = lpf->R_len = NULL;
69 lpf->S_ptr = lpf->S_len = NULL;
71 lpf->P_row = lpf->P_col = NULL;
72 lpf->Q_row = lpf->Q_col = NULL;
77 lpf->work1 = lpf->work2 = NULL;
81 /***********************************************************************
84 * lpf_factorize - compute LP basis factorization
89 * int lpf_factorize(LPF *lpf, int m, const int bh[], int (*col)
90 * (void *info, int j, int ind[], double val[]), void *info);
94 * The routine lpf_factorize computes the factorization of the basis
95 * matrix B specified by the routine col.
97 * The parameter lpf specified the basis factorization data structure
98 * created with the routine lpf_create_it.
100 * The parameter m specifies the order of B, m > 0.
102 * The array bh specifies the basis header: bh[j], 1 <= j <= m, is the
103 * number of j-th column of B in some original matrix. The array bh is
104 * optional and can be specified as NULL.
106 * The formal routine col specifies the matrix B to be factorized. To
107 * obtain j-th column of A the routine lpf_factorize calls the routine
108 * col with the parameter j (1 <= j <= n). In response the routine col
109 * should store row indices and numerical values of non-zero elements
110 * of j-th column of B to locations ind[1,...,len] and val[1,...,len],
111 * respectively, where len is the number of non-zeros in j-th column
112 * returned on exit. Neither zero nor duplicate elements are allowed.
114 * The parameter info is a transit pointer passed to the routine col.
118 * 0 The factorization has been successfully computed.
121 * The specified matrix is singular within the working precision.
124 * The specified matrix is ill-conditioned.
126 * For more details see comments to the routine luf_factorize. */
128 int lpf_factorize(LPF *lpf, int m, const int bh[], int (*col)
129 (void *info, int j, int ind[], double val[]), void *info)
137 xfault("lpf_factorize: m = %d; invalid parameter\n", m);
139 xfault("lpf_factorize: m = %d; matrix too big\n", m);
140 lpf->m0 = lpf->m = m;
141 /* invalidate the factorization */
143 /* allocate/reallocate arrays, if necessary */
144 if (lpf->R_ptr == NULL)
145 lpf->R_ptr = xcalloc(1+lpf->n_max, sizeof(int));
146 if (lpf->R_len == NULL)
147 lpf->R_len = xcalloc(1+lpf->n_max, sizeof(int));
148 if (lpf->S_ptr == NULL)
149 lpf->S_ptr = xcalloc(1+lpf->n_max, sizeof(int));
150 if (lpf->S_len == NULL)
151 lpf->S_len = xcalloc(1+lpf->n_max, sizeof(int));
152 if (lpf->scf == NULL)
153 lpf->scf = scf_create_it(lpf->n_max);
154 if (lpf->v_ind == NULL)
155 lpf->v_ind = xcalloc(1+lpf->v_size, sizeof(int));
156 if (lpf->v_val == NULL)
157 lpf->v_val = xcalloc(1+lpf->v_size, sizeof(double));
159 { if (lpf->P_row != NULL) xfree(lpf->P_row);
160 if (lpf->P_col != NULL) xfree(lpf->P_col);
161 if (lpf->Q_row != NULL) xfree(lpf->Q_row);
162 if (lpf->Q_col != NULL) xfree(lpf->Q_col);
163 if (lpf->work1 != NULL) xfree(lpf->work1);
164 if (lpf->work2 != NULL) xfree(lpf->work2);
165 lpf->m0_max = m + 100;
166 lpf->P_row = xcalloc(1+lpf->m0_max+lpf->n_max, sizeof(int));
167 lpf->P_col = xcalloc(1+lpf->m0_max+lpf->n_max, sizeof(int));
168 lpf->Q_row = xcalloc(1+lpf->m0_max+lpf->n_max, sizeof(int));
169 lpf->Q_col = xcalloc(1+lpf->m0_max+lpf->n_max, sizeof(int));
170 lpf->work1 = xcalloc(1+lpf->m0_max+lpf->n_max, sizeof(double));
171 lpf->work2 = xcalloc(1+lpf->m0_max+lpf->n_max, sizeof(double));
173 /* try to factorize the basis matrix */
174 switch (luf_factorize(lpf->luf, m, col, info))
186 /* the basis matrix has been successfully factorized */
189 /* store the basis matrix for debugging */
190 if (lpf->B != NULL) xfree(lpf->B);
192 lpf->B = B = xcalloc(1+m*m, sizeof(double));
193 ind = xcalloc(1+m, sizeof(int));
194 val = xcalloc(1+m, sizeof(double));
195 for (k = 1; k <= m * m; k++)
197 for (j = 1; j <= m; j++)
198 { len = col(info, j, ind, val);
199 xassert(0 <= len && len <= m);
200 for (k = 1; k <= len; k++)
202 xassert(1 <= i && i <= m);
203 xassert(B[(i - 1) * m + j] == 0.0);
204 xassert(val[k] != 0.0);
205 B[(i - 1) * m + j] = val[k];
211 /* B = B0, so there are no additional rows/columns */
213 /* reset the Schur complement factorization */
214 scf_reset_it(lpf->scf);
216 for (k = 1; k <= m; k++)
217 { lpf->P_row[k] = lpf->P_col[k] = k;
218 lpf->Q_row[k] = lpf->Q_col[k] = k;
220 /* make all SVA locations free */
223 done: /* return to the calling program */
227 /***********************************************************************
228 * The routine r_prod computes the product y := y + alpha * R * x,
229 * where x is a n-vector, alpha is a scalar, y is a m0-vector.
231 * Since matrix R is available by columns, the product is computed as
232 * a linear combination:
234 * y := y + alpha * (R[1] * x[1] + ... + R[n] * x[n]),
236 * where R[j] is j-th column of R. */
238 static void r_prod(LPF *lpf, double y[], double a, const double x[])
240 int *R_ptr = lpf->R_ptr;
241 int *R_len = lpf->R_len;
242 int *v_ind = lpf->v_ind;
243 double *v_val = lpf->v_val;
244 int j, beg, end, ptr;
246 for (j = 1; j <= n; j++)
247 { if (x[j] == 0.0) continue;
248 /* y := y + alpha * R[j] * x[j] */
251 end = beg + R_len[j];
252 for (ptr = beg; ptr < end; ptr++)
253 y[v_ind[ptr]] += t * v_val[ptr];
258 /***********************************************************************
259 * The routine rt_prod computes the product y := y + alpha * R' * x,
260 * where R' is a matrix transposed to R, x is a m0-vector, alpha is a
261 * scalar, y is a n-vector.
263 * Since matrix R is available by columns, the product components are
264 * computed as inner products:
266 * y[j] := y[j] + alpha * (j-th column of R) * x
268 * for j = 1, 2, ..., n. */
270 static void rt_prod(LPF *lpf, double y[], double a, const double x[])
272 int *R_ptr = lpf->R_ptr;
273 int *R_len = lpf->R_len;
274 int *v_ind = lpf->v_ind;
275 double *v_val = lpf->v_val;
276 int j, beg, end, ptr;
278 for (j = 1; j <= n; j++)
279 { /* t := (j-th column of R) * x */
282 end = beg + R_len[j];
283 for (ptr = beg; ptr < end; ptr++)
284 t += v_val[ptr] * x[v_ind[ptr]];
285 /* y[j] := y[j] + alpha * t */
291 /***********************************************************************
292 * The routine s_prod computes the product y := y + alpha * S * x,
293 * where x is a m0-vector, alpha is a scalar, y is a n-vector.
295 * Since matrix S is available by rows, the product components are
296 * computed as inner products:
298 * y[i] = y[i] + alpha * (i-th row of S) * x
300 * for i = 1, 2, ..., n. */
302 static void s_prod(LPF *lpf, double y[], double a, const double x[])
304 int *S_ptr = lpf->S_ptr;
305 int *S_len = lpf->S_len;
306 int *v_ind = lpf->v_ind;
307 double *v_val = lpf->v_val;
308 int i, beg, end, ptr;
310 for (i = 1; i <= n; i++)
311 { /* t := (i-th row of S) * x */
314 end = beg + S_len[i];
315 for (ptr = beg; ptr < end; ptr++)
316 t += v_val[ptr] * x[v_ind[ptr]];
317 /* y[i] := y[i] + alpha * t */
323 /***********************************************************************
324 * The routine st_prod computes the product y := y + alpha * S' * x,
325 * where S' is a matrix transposed to S, x is a n-vector, alpha is a
326 * scalar, y is m0-vector.
328 * Since matrix R is available by rows, the product is computed as a
329 * linear combination:
331 * y := y + alpha * (S'[1] * x[1] + ... + S'[n] * x[n]),
333 * where S'[i] is i-th row of S. */
335 static void st_prod(LPF *lpf, double y[], double a, const double x[])
337 int *S_ptr = lpf->S_ptr;
338 int *S_len = lpf->S_len;
339 int *v_ind = lpf->v_ind;
340 double *v_val = lpf->v_val;
341 int i, beg, end, ptr;
343 for (i = 1; i <= n; i++)
344 { if (x[i] == 0.0) continue;
345 /* y := y + alpha * S'[i] * x[i] */
348 end = beg + S_len[i];
349 for (ptr = beg; ptr < end; ptr++)
350 y[v_ind[ptr]] += t * v_val[ptr];
356 /***********************************************************************
357 * The routine check_error computes the maximal relative error between
358 * left- and right-hand sides for the system B * x = b (if tr is zero)
359 * or B' * x = b (if tr is non-zero), where B' is a matrix transposed
360 * to B. (This routine is intended for debugging only.) */
362 static void check_error(LPF *lpf, int tr, const double x[],
367 double d, dmax = 0.0, s, t, tmax;
368 for (i = 1; i <= m; i++)
371 for (j = 1; j <= m; j++)
373 t = B[m * (i - 1) + j] * x[j];
375 t = B[m * (j - 1) + i] * x[j];
376 if (tmax < fabs(t)) tmax = fabs(t);
379 d = fabs(s - b[i]) / tmax;
380 if (dmax < d) dmax = d;
383 xprintf("%s: dmax = %g; relative error too large\n",
384 !tr ? "lpf_ftran" : "lpf_btran", dmax);
389 /***********************************************************************
392 * lpf_ftran - perform forward transformation (solve system B*x = b)
396 * #include "glplpf.h"
397 * void lpf_ftran(LPF *lpf, double x[]);
401 * The routine lpf_ftran performs forward transformation, i.e. solves
402 * the system B*x = b, where B is the basis matrix, x is the vector of
403 * unknowns to be computed, b is the vector of right-hand sides.
405 * On entry elements of the vector b should be stored in dense format
406 * in locations x[1], ..., x[m], where m is the number of rows. On exit
407 * the routine stores elements of the vector x in the same locations.
411 * Solution of the system B * x = b can be obtained by solving the
412 * following augmented system:
414 * ( B F^) ( x ) ( b )
416 * ( G^ H^) ( y ) ( 0 )
418 * which, using the main equality, can be written as follows:
420 * ( L0 0 ) ( U0 R ) ( x ) ( b )
421 * P ( ) ( ) Q ( ) = ( )
422 * ( S I ) ( 0 C ) ( y ) ( 0 )
426 * ( x ) ( U0 R )-1 ( L0 0 )-1 ( b )
427 * ( ) = Q' ( ) ( ) P' ( )
428 * ( y ) ( 0 C ) ( S I ) ( 0 )
430 * Thus, computing the solution includes the following steps:
438 * 2. Solve the system
440 * ( f1 ) ( L0 0 )-1 ( f ) ( L0 0 ) ( f1 ) ( f )
441 * ( ) = ( ) ( ) => ( ) ( ) = ( )
442 * ( g1 ) ( S I ) ( g ) ( S I ) ( g1 ) ( g )
444 * from which it follows that:
446 * { L0 * f1 = f f1 = inv(L0) * f
448 * { S * f1 + g1 = g g1 = g - S * f1
450 * 3. Solve the system
452 * ( f2 ) ( U0 R )-1 ( f1 ) ( U0 R ) ( f2 ) ( f1 )
453 * ( ) = ( ) ( ) => ( ) ( ) = ( )
454 * ( g2 ) ( 0 C ) ( g1 ) ( 0 C ) ( g2 ) ( g1 )
456 * from which it follows that:
458 * { U0 * f2 + R * g2 = f1 f2 = inv(U0) * (f1 - R * g2)
460 * { C * g2 = g1 g2 = inv(C) * g1
468 void lpf_ftran(LPF *lpf, double x[])
472 int *P_col = lpf->P_col;
473 int *Q_col = lpf->Q_col;
474 double *fg = lpf->work1;
482 xfault("lpf_ftran: the factorization is not valid\n");
483 xassert(0 <= m && m <= m0 + n);
485 /* save the right-hand side vector */
486 b = xcalloc(1+m, sizeof(double));
487 for (i = 1; i <= m; i++) b[i] = x[i];
489 /* (f g) := inv(P) * (b 0) */
490 for (i = 1; i <= m0 + n; i++)
491 fg[i] = ((ii = P_col[i]) <= m ? x[ii] : 0.0);
492 /* f1 := inv(L0) * f */
493 luf_f_solve(lpf->luf, 0, f);
494 /* g1 := g - S * f1 */
495 s_prod(lpf, g, -1.0, f);
496 /* g2 := inv(C) * g1 */
497 scf_solve_it(lpf->scf, 0, g);
498 /* f2 := inv(U0) * (f1 - R * g2) */
499 r_prod(lpf, f, -1.0, g);
500 luf_v_solve(lpf->luf, 0, f);
501 /* (x y) := inv(Q) * (f2 g2) */
502 for (i = 1; i <= m; i++)
505 /* check relative error in solution */
506 check_error(lpf, 0, x, b);
512 /***********************************************************************
515 * lpf_btran - perform backward transformation (solve system B'*x = b)
519 * #include "glplpf.h"
520 * void lpf_btran(LPF *lpf, double x[]);
524 * The routine lpf_btran performs backward transformation, i.e. solves
525 * the system B'*x = b, where B' is a matrix transposed to the basis
526 * matrix B, x is the vector of unknowns to be computed, b is the vector
527 * of right-hand sides.
529 * On entry elements of the vector b should be stored in dense format
530 * in locations x[1], ..., x[m], where m is the number of rows. On exit
531 * the routine stores elements of the vector x in the same locations.
535 * Solution of the system B' * x = b, where B' is a matrix transposed
536 * to B, can be obtained by solving the following augmented system:
538 * ( B F^)T ( x ) ( b )
540 * ( G^ H^) ( y ) ( 0 )
542 * which, using the main equality, can be written as follows:
544 * T ( U0 R )T ( L0 0 )T T ( x ) ( b )
545 * Q ( ) ( ) P ( ) = ( )
546 * ( 0 C ) ( S I ) ( y ) ( 0 )
548 * or, equivalently, as follows:
550 * ( U'0 0 ) ( L'0 S') ( x ) ( b )
551 * Q' ( ) ( ) P' ( ) = ( )
552 * ( R' C') ( 0 I ) ( y ) ( 0 )
556 * ( x ) ( L'0 S')-1 ( U'0 0 )-1 ( b )
557 * ( ) = P ( ) ( ) Q ( )
558 * ( y ) ( 0 I ) ( R' C') ( 0 )
560 * Thus, computing the solution includes the following steps:
568 * 2. Solve the system
570 * ( f1 ) ( U'0 0 )-1 ( f ) ( U'0 0 ) ( f1 ) ( f )
571 * ( ) = ( ) ( ) => ( ) ( ) = ( )
572 * ( g1 ) ( R' C') ( g ) ( R' C') ( g1 ) ( g )
574 * from which it follows that:
576 * { U'0 * f1 = f f1 = inv(U'0) * f
578 * { R' * f1 + C' * g1 = g g1 = inv(C') * (g - R' * f1)
580 * 3. Solve the system
582 * ( f2 ) ( L'0 S')-1 ( f1 ) ( L'0 S') ( f2 ) ( f1 )
583 * ( ) = ( ) ( ) => ( ) ( ) = ( )
584 * ( g2 ) ( 0 I ) ( g1 ) ( 0 I ) ( g2 ) ( g1 )
586 * from which it follows that:
588 * { L'0 * f2 + S' * g2 = f1
589 * { => f2 = inv(L'0) * ( f1 - S' * g2)
598 void lpf_btran(LPF *lpf, double x[])
602 int *P_row = lpf->P_row;
603 int *Q_row = lpf->Q_row;
604 double *fg = lpf->work1;
612 xfault("lpf_btran: the factorization is not valid\n");
613 xassert(0 <= m && m <= m0 + n);
615 /* save the right-hand side vector */
616 b = xcalloc(1+m, sizeof(double));
617 for (i = 1; i <= m; i++) b[i] = x[i];
619 /* (f g) := Q * (b 0) */
620 for (i = 1; i <= m0 + n; i++)
621 fg[i] = ((ii = Q_row[i]) <= m ? x[ii] : 0.0);
622 /* f1 := inv(U'0) * f */
623 luf_v_solve(lpf->luf, 1, f);
624 /* g1 := inv(C') * (g - R' * f1) */
625 rt_prod(lpf, g, -1.0, f);
626 scf_solve_it(lpf->scf, 1, g);
629 /* f2 := inv(L'0) * (f1 - S' * g2) */
630 st_prod(lpf, f, -1.0, g);
631 luf_f_solve(lpf->luf, 1, f);
632 /* (x y) := P * (f2 g2) */
633 for (i = 1; i <= m; i++)
636 /* check relative error in solution */
637 check_error(lpf, 1, x, b);
643 /***********************************************************************
644 * The routine enlarge_sva enlarges the Sparse Vector Area to new_size
645 * locations by reallocating the arrays v_ind and v_val. */
647 static void enlarge_sva(LPF *lpf, int new_size)
648 { int v_size = lpf->v_size;
649 int used = lpf->v_ptr - 1;
650 int *v_ind = lpf->v_ind;
651 double *v_val = lpf->v_val;
652 xassert(v_size < new_size);
653 while (v_size < new_size) v_size += v_size;
654 lpf->v_size = v_size;
655 lpf->v_ind = xcalloc(1+v_size, sizeof(int));
656 lpf->v_val = xcalloc(1+v_size, sizeof(double));
658 memcpy(&lpf->v_ind[1], &v_ind[1], used * sizeof(int));
659 memcpy(&lpf->v_val[1], &v_val[1], used * sizeof(double));
665 /***********************************************************************
668 * lpf_update_it - update LP basis factorization
672 * #include "glplpf.h"
673 * int lpf_update_it(LPF *lpf, int j, int bh, int len, const int ind[],
674 * const double val[]);
678 * The routine lpf_update_it updates the factorization of the basis
679 * matrix B after replacing its j-th column by a new vector.
681 * The parameter j specifies the number of column of B, which has been
682 * replaced, 1 <= j <= m, where m is the order of B.
684 * The parameter bh specifies the basis header entry for the new column
685 * of B, which is the number of the new column in some original matrix.
686 * This parameter is optional and can be specified as 0.
688 * Row indices and numerical values of non-zero elements of the new
689 * column of B should be placed in locations ind[1], ..., ind[len] and
690 * val[1], ..., val[len], resp., where len is the number of non-zeros
691 * in the column. Neither zero nor duplicate elements are allowed.
695 * 0 The factorization has been successfully updated.
698 * New basis B is singular within the working precision.
701 * Maximal number of additional rows and columns has been reached.
705 * Let j-th column of the current basis matrix B have to be replaced by
706 * a new column a. This replacement is equivalent to removing the old
707 * j-th column by fixing it at zero and introducing the new column as
712 * ( ) ---> ( G^ H^| 0 )
713 * ( G^ H^) (-------+---)
716 * where ej is a unit vector with 1 in j-th position which used to fix
717 * the old j-th column of B (at zero). Then using the main equality we
720 * ( B F^| a ) ( B0 F | f )
721 * ( | ) ( P 0 ) ( | ) ( Q 0 )
722 * ( G^ H^| 0 ) = ( ) ( G H | g ) ( ) =
723 * (-------+---) ( 0 1 ) (-------+---) ( 0 1 )
724 * ( e'j 0 | 0 ) ( v' w'| 0 )
726 * [ ( B0 F )| ( f ) ] [ ( B0 F ) | ( f ) ]
727 * [ P ( )| P ( ) ] ( Q 0 ) [ P ( ) Q| P ( ) ]
728 * = [ ( G H )| ( g ) ] ( ) = [ ( G H ) | ( g ) ]
729 * [------------+-------- ] ( 0 1 ) [-------------+---------]
730 * [ ( v' w')| 0 ] [ ( v' w') Q| 0 ]
734 * ( a ) ( f ) ( f ) ( a )
735 * ( ) = P ( ) => ( ) = P' * ( )
736 * ( 0 ) ( g ) ( g ) ( 0 )
738 * ( ej ) ( v ) ( v ) ( ej )
739 * ( e'j 0 ) = ( v' w' ) Q => ( ) = Q' ( ) => ( ) = Q ( )
740 * ( 0 ) ( w ) ( w ) ( 0 )
745 * ( P 0 ) (---+------) ( Q 0 ) ( B0 new F )
746 * ( ) ( G | H g ) ( ) = new P ( ) new Q
747 * ( 0 1 ) ( | ) ( 0 1 ) ( new G new H )
752 * new F = ( F f ), new G = ( ), new H = ( ),
756 * new P = ( ) , new Q = ( ) .
759 * The factorization structure for the new augmented matrix remains the
762 * ( B0 new F ) ( L0 0 ) ( U0 new R )
763 * new P ( ) new Q = ( ) ( )
764 * ( new G new H ) ( new S I ) ( 0 new C )
768 * new F = L0 * new R =>
770 * new R = inv(L0) * new F = inv(L0) * (F f) = ( R inv(L0)*f )
772 * new G = new S * U0 =>
775 * new S = new G * inv(U0) = ( ) * inv(U0) = ( )
776 * ( v') ( v'*inv(U0) )
778 * new H = new S * new R + new C =>
780 * new C = new H - new S * new R =
783 * = ( ) - ( ) * ( R inv(L0)*f ) =
784 * ( w' 0 ) ( v'*inv(U0) )
786 * ( H - S*R g - S*inv(L0)*f ) ( C x )
788 * ( w'- v'*inv(U0)*R -v'*inv(U0)*inv(L0)*f) ( y' z )
790 * Note that new C is resulted by expanding old C with new column x,
791 * row y', and diagonal element z, where:
793 * x = g - S * inv(L0) * f = g - S * (new column of R)
795 * y = w - R'* inv(U'0)* v = w - R'* (new row of S)
797 * z = - (new row of S) * (new column of R)
799 * Finally, to replace old B by new B we have to permute j-th and last
800 * (just added) columns of the matrix
808 * and to keep the main equality do the same for matrix Q. */
810 int lpf_update_it(LPF *lpf, int j, int bh, int len, const int ind[],
818 int *R_ptr = lpf->R_ptr;
819 int *R_len = lpf->R_len;
820 int *S_ptr = lpf->S_ptr;
821 int *S_len = lpf->S_len;
822 int *P_row = lpf->P_row;
823 int *P_col = lpf->P_col;
824 int *Q_row = lpf->Q_row;
825 int *Q_col = lpf->Q_col;
826 int v_ptr = lpf->v_ptr;
827 int *v_ind = lpf->v_ind;
828 double *v_val = lpf->v_val;
829 double *a = lpf->work2; /* new column */
830 double *fg = lpf->work1, *f = fg, *g = fg + m0;
831 double *vw = lpf->work2, *v = vw, *w = vw + m0;
832 double *x = g, *y = w, z;
836 xfault("lpf_update_it: the factorization is not valid\n");
837 if (!(1 <= j && j <= m))
838 xfault("lpf_update_it: j = %d; column number out of range\n",
840 xassert(0 <= m && m <= m0 + n);
841 /* check if the basis factorization can be expanded */
847 /* convert new j-th column of B to dense format */
848 for (i = 1; i <= m; i++)
850 for (k = 1; k <= len; k++)
852 if (!(1 <= i && i <= m))
853 xfault("lpf_update_it: ind[%d] = %d; row number out of rang"
856 xfault("lpf_update_it: ind[%d] = %d; duplicate row index no"
857 "t allowed\n", k, i);
859 xfault("lpf_update_it: val[%d] = %g; zero element not allow"
864 /* change column in the basis matrix for debugging */
865 for (i = 1; i <= m; i++)
866 B[(i - 1) * m + j] = a[i];
868 /* (f g) := inv(P) * (a 0) */
869 for (i = 1; i <= m0+n; i++)
870 fg[i] = ((ii = P_col[i]) <= m ? a[ii] : 0.0);
871 /* (v w) := Q * (ej 0) */
872 for (i = 1; i <= m0+n; i++) vw[i] = 0.0;
874 /* f1 := inv(L0) * f (new column of R) */
875 luf_f_solve(lpf->luf, 0, f);
876 /* v1 := inv(U'0) * v (new row of S) */
877 luf_v_solve(lpf->luf, 1, v);
878 /* we need at most 2 * m0 available locations in the SVA to store
879 new column of matrix R and new row of matrix S */
880 if (lpf->v_size < v_ptr + m0 + m0)
881 { enlarge_sva(lpf, v_ptr + m0 + m0);
885 /* store new column of R */
887 for (i = 1; i <= m0; i++)
889 v_ind[v_ptr] = i, v_val[v_ptr] = f[i], v_ptr++;
891 R_len[n+1] = v_ptr - lpf->v_ptr;
893 /* store new row of S */
895 for (i = 1; i <= m0; i++)
897 v_ind[v_ptr] = i, v_val[v_ptr] = v[i], v_ptr++;
899 S_len[n+1] = v_ptr - lpf->v_ptr;
901 /* x := g - S * f1 (new column of C) */
902 s_prod(lpf, x, -1.0, f);
903 /* y := w - R' * v1 (new row of C) */
904 rt_prod(lpf, y, -1.0, v);
905 /* z := - v1 * f1 (new diagonal element of C) */
907 for (i = 1; i <= m0; i++) z -= v[i] * f[i];
908 /* update factorization of new matrix C */
909 switch (scf_update_exp(lpf->scf, x, y, z))
921 /* expand matrix P */
922 P_row[m0+n+1] = P_col[m0+n+1] = m0+n+1;
923 /* expand matrix Q */
924 Q_row[m0+n+1] = Q_col[m0+n+1] = m0+n+1;
925 /* permute j-th and last (just added) column of matrix Q */
926 i = Q_col[j], ii = Q_col[m0+n+1];
927 Q_row[i] = m0+n+1, Q_col[m0+n+1] = i;
928 Q_row[ii] = j, Q_col[j] = ii;
929 /* increase the number of additional rows and columns */
931 xassert(lpf->n <= lpf->n_max);
932 /* the factorization has been successfully updated */
934 done: /* return to the calling program */
938 /***********************************************************************
941 * lpf_delete_it - delete LP basis factorization
945 * #include "glplpf.h"
946 * void lpf_delete_it(LPF *lpf)
950 * The routine lpf_delete_it deletes LP basis factorization specified
951 * by the parameter lpf and frees all memory allocated to this program
954 void lpf_delete_it(LPF *lpf)
955 { luf_delete_it(lpf->luf);
957 if (lpf->B != NULL) xfree(lpf->B);
959 xassert(lpf->B == NULL);
961 if (lpf->R_ptr != NULL) xfree(lpf->R_ptr);
962 if (lpf->R_len != NULL) xfree(lpf->R_len);
963 if (lpf->S_ptr != NULL) xfree(lpf->S_ptr);
964 if (lpf->S_len != NULL) xfree(lpf->S_len);
965 if (lpf->scf != NULL) scf_delete_it(lpf->scf);
966 if (lpf->P_row != NULL) xfree(lpf->P_row);
967 if (lpf->P_col != NULL) xfree(lpf->P_col);
968 if (lpf->Q_row != NULL) xfree(lpf->Q_row);
969 if (lpf->Q_col != NULL) xfree(lpf->Q_col);
970 if (lpf->v_ind != NULL) xfree(lpf->v_ind);
971 if (lpf->v_val != NULL) xfree(lpf->v_val);
972 if (lpf->work1 != NULL) xfree(lpf->work1);
973 if (lpf->work2 != NULL) xfree(lpf->work2);