⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 glpscf.c

📁 著名的大规模线性规划求解器源码GLPK.C语言版本,可以修剪.内有详细帮助文档.
💻 C
📖 第 1 页 / 共 2 页
字号:
/* glpscf.c (Schur complement factorization) *//************************************************************************  This code is part of GLPK (GNU Linear Programming Kit).**  Copyright (C) 2000,01,02,03,04,05,06,07,08,2009 Andrew Makhorin,*  Department for Applied Informatics, Moscow Aviation Institute,*  Moscow, Russia. All rights reserved. E-mail: <mao@mai2.rcnet.ru>.**  GLPK is free software: you can redistribute it and/or modify it*  under the terms of the GNU General Public License as published by*  the Free Software Foundation, either version 3 of the License, or*  (at your option) any later version.**  GLPK is distributed in the hope that it will be useful, but WITHOUT*  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY*  or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public*  License for more details.**  You should have received a copy of the GNU General Public License*  along with GLPK. If not, see <http://www.gnu.org/licenses/>.***********************************************************************/#include "glplib.h"#include "glpscf.h"#define xfault xerror#define _GLPSCF_DEBUG 0#define eps 1e-10/************************************************************************  NAME**  scf_create_it - create Schur complement factorization**  SYNOPSIS**  #include "glpscf.h"*  SCF *scf_create_it(int n_max);**  DESCRIPTION**  The routine scf_create_it creates the factorization of matrix C,*  which initially has no rows and columns.**  The parameter n_max specifies the maximal order of matrix C to be*  factorized, 1 <= n_max <= 32767.**  RETURNS**  The routine scf_create_it returns a pointer to the structure SCF,*  which defines the factorization. */SCF *scf_create_it(int n_max){     SCF *scf;#if _GLPSCF_DEBUG      xprintf("scf_create_it: warning: debug mode enabled\n");#endif      if (!(1 <= n_max && n_max <= 32767))         xfault("scf_create_it: n_max = %d; invalid parameter\n",            n_max);      scf = xmalloc(sizeof(SCF));      scf->n_max = n_max;      scf->n = 0;      scf->f = xcalloc(1 + n_max * n_max, sizeof(double));      scf->u = xcalloc(1 + n_max * (n_max + 1) / 2, sizeof(double));      scf->p = xcalloc(1 + n_max, sizeof(int));      scf->t_opt = SCF_TBG;      scf->rank = 0;#if _GLPSCF_DEBUG      scf->c = xcalloc(1 + n_max * n_max, sizeof(double));#else      scf->c = NULL;#endif      scf->w = xcalloc(1 + n_max, sizeof(double));      return scf;}/************************************************************************  The routine f_loc determines location of matrix element F[i,j] in*  the one-dimensional array f. */static int f_loc(SCF *scf, int i, int j){     int n_max = scf->n_max;      int n = scf->n;      xassert(1 <= i && i <= n);      xassert(1 <= j && j <= n);      return (i - 1) * n_max + j;}/************************************************************************  The routine u_loc determines location of matrix element U[i,j] in*  the one-dimensional array u. */static int u_loc(SCF *scf, int i, int j){     int n_max = scf->n_max;      int n = scf->n;      xassert(1 <= i && i <= n);      xassert(i <= j && j <= n);      return (i - 1) * n_max + j - i * (i - 1) / 2;}/************************************************************************  The routine bg_transform applies Bartels-Golub version of gaussian*  elimination to restore triangular structure of matrix U.**  On entry matrix U has the following structure:**        1       k         n*     1  * * * * * * * * * **        . * * * * * * * * **        . . * * * * * * * **        . . . * * * * * * **     k  . . . . * * * * * **        . . . . . * * * * **        . . . . . . * * * **        . . . . . . . * * **        . . . . . . . . * **     n  . . . . # # # # # #**  where '#' is a row spike to be eliminated.**  Elements of n-th row are passed separately in locations un[k], ...,*  un[n]. On exit the content of the array un is destroyed.**  REFERENCES**  R.H.Bartels, G.H.Golub, "The Simplex Method of Linear Programming*  Using LU-decomposition", Comm. ACM, 12, pp. 266-68, 1969. */static void bg_transform(SCF *scf, int k, double un[]){     int n = scf->n;      double *f = scf->f;      double *u = scf->u;      int j, k1, kj, kk, n1, nj;      double t;      xassert(1 <= k && k <= n);      /* main elimination loop */      for (k = k; k < n; k++)      {  /* determine location of U[k,k] */         kk = u_loc(scf, k, k);         /* determine location of F[k,1] */         k1 = f_loc(scf, k, 1);         /* determine location of F[n,1] */         n1 = f_loc(scf, n, 1);         /* if |U[k,k]| < |U[n,k]|, interchange k-th and n-th rows to            provide |U[k,k]| >= |U[n,k]| */         if (fabs(u[kk]) < fabs(un[k]))         {  /* interchange k-th and n-th rows of matrix U */            for (j = k, kj = kk; j <= n; j++, kj++)               t = u[kj], u[kj] = un[j], un[j] = t;            /* interchange k-th and n-th rows of matrix F to keep the               main equality F * C = U * P */            for (j = 1, kj = k1, nj = n1; j <= n; j++, kj++, nj++)               t = f[kj], f[kj] = f[nj], f[nj] = t;         }         /* now |U[k,k]| >= |U[n,k]| */         /* if U[k,k] is too small in the magnitude, replace U[k,k] and            U[n,k] by exact zero */         if (fabs(u[kk]) < eps) u[kk] = un[k] = 0.0;         /* if U[n,k] is already zero, elimination is not needed */         if (un[k] == 0.0) continue;         /* compute gaussian multiplier t = U[n,k] / U[k,k] */         t = un[k] / u[kk];         /* apply gaussian elimination to nullify U[n,k] */         /* (n-th row of U) := (n-th row of U) - t * (k-th row of U) */         for (j = k+1, kj = kk+1; j <= n; j++, kj++)            un[j] -= t * u[kj];         /* (n-th row of F) := (n-th row of F) - t * (k-th row of F)            to keep the main equality F * C = U * P */         for (j = 1, kj = k1, nj = n1; j <= n; j++, kj++, nj++)            f[nj] -= t * f[kj];      }      /* if U[n,n] is too small in the magnitude, replace it by exact         zero */      if (fabs(un[n]) < eps) un[n] = 0.0;      /* store U[n,n] in a proper location */      u[u_loc(scf, n, n)] = un[n];      return;}/************************************************************************  The routine givens computes the parameters of Givens plane rotation*  c = cos(teta) and s = sin(teta) such that:**     ( c -s ) ( a )   ( r )*     (      ) (   ) = (   ) ,*     ( s  c ) ( b )   ( 0 )**  where a and b are given scalars.**  REFERENCES**  G.H.Golub, C.F.Van Loan, "Matrix Computations", 2nd ed. */static void givens(double a, double b, double *c, double *s){     double t;      if (b == 0.0)         (*c) = 1.0, (*s) = 0.0;      else if (fabs(a) <= fabs(b))         t = - a / b, (*s) = 1.0 / sqrt(1.0 + t * t), (*c) = (*s) * t;      else         t = - b / a, (*c) = 1.0 / sqrt(1.0 + t * t), (*s) = (*c) * t;      return;}/*----------------------------------------------------------------------*  The routine gr_transform applies Givens plane rotations to restore*  triangular structure of matrix U.**  On entry matrix U has the following structure:**        1       k         n*     1  * * * * * * * * * **        . * * * * * * * * **        . . * * * * * * * **        . . . * * * * * * **     k  . . . . * * * * * **        . . . . . * * * * **        . . . . . . * * * **        . . . . . . . * * **        . . . . . . . . * **     n  . . . . # # # # # #**  where '#' is a row spike to be eliminated.**  Elements of n-th row are passed separately in locations un[k], ...,*  un[n]. On exit the content of the array un is destroyed.**  REFERENCES**  R.H.Bartels, G.H.Golub, "The Simplex Method of Linear Programming*  Using LU-decomposition", Comm. ACM, 12, pp. 266-68, 1969. */static void gr_transform(SCF *scf, int k, double un[]){     int n = scf->n;      double *f = scf->f;      double *u = scf->u;      int j, k1, kj, kk, n1, nj;      double c, s;      xassert(1 <= k && k <= n);      /* main elimination loop */      for (k = k; k < n; k++)      {  /* determine location of U[k,k] */         kk = u_loc(scf, k, k);         /* determine location of F[k,1] */         k1 = f_loc(scf, k, 1);         /* determine location of F[n,1] */         n1 = f_loc(scf, n, 1);         /* if both U[k,k] and U[n,k] are too small in the magnitude,            replace them by exact zero */         if (fabs(u[kk]) < eps && fabs(un[k]) < eps)            u[kk] = un[k] = 0.0;         /* if U[n,k] is already zero, elimination is not needed */         if (un[k] == 0.0) continue;         /* compute the parameters of Givens plane rotation */         givens(u[kk], un[k], &c, &s);         /* apply Givens rotation to k-th and n-th rows of matrix U */         for (j = k, kj = kk; j <= n; j++, kj++)         {  double ukj = u[kj], unj = un[j];            u[kj] = c * ukj - s * unj;            un[j] = s * ukj + c * unj;         }         /* apply Givens rotation to k-th and n-th rows of matrix F            to keep the main equality F * C = U * P */         for (j = 1, kj = k1, nj = n1; j <= n; j++, kj++, nj++)         {  double fkj = f[kj], fnj = f[nj];            f[kj] = c * fkj - s * fnj;            f[nj] = s * fkj + c * fnj;         }      }      /* if U[n,n] is too small in the magnitude, replace it by exact         zero */      if (fabs(un[n]) < eps) un[n] = 0.0;      /* store U[n,n] in a proper location */      u[u_loc(scf, n, n)] = un[n];      return;}/************************************************************************  The routine transform restores triangular structure of matrix U.*  It is a driver to the routines bg_transform and gr_transform (see*  comments to these routines above). */static void transform(SCF *scf, int k, double un[]){     switch (scf->t_opt)      {  case SCF_TBG:            bg_transform(scf, k, un);            break;         case SCF_TGR:            gr_transform(scf, k, un);            break;         default:            xassert(scf != scf);      }      return;}/************************************************************************  The routine estimate_rank estimates the rank of matrix C.**  Since all transformations applied to matrix F are non-singular,*  and F is assumed to be well conditioned, from the main equaility*  F * C = U * P it follows that rank(C) = rank(U), where rank(U) is*  estimated as the number of non-zero diagonal elements of U. */static int estimate_rank(SCF *scf){     int n_max = scf->n_max;      int n = scf->n;      double *u = scf->u;      int i, ii, inc, rank = 0;      for (i = 1, ii = u_loc(scf, i, i), inc = n_max; i <= n;         i++, ii += inc, inc--)         if (u[ii] != 0.0) rank++;      return rank;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -