[BACK]Return to Rsimp.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / TiGERS_0.9

Annotation of OpenXM_contrib/TiGERS_0.9/Rsimp.c, Revision 1.1

1.1     ! maekawa     1: /*
        !             2: ** Rsimp.c                                 Birk Huber, 4/99
        !             3: ** -- definitions of linear programming data structure and
        !             4: ** -- basic implementation of revised simplex method.
        !             5: **
        !             6: **
        !             7: ** TiGERS,  Toric Groebner Basis Enumeration by Reverse Search
        !             8: ** copyright (c) 1999  Birk Huber
        !             9: **
        !            10: */
        !            11: #include <stdio.h>
        !            12: #include <math.h>
        !            13: #define RSIMP_H 1
        !            14: #include "matrices.h"
        !            15: #include "Rsimp.h"
        !            16: #define verbose 0
        !            17: #define zero_tol RS_zt
        !            18:
        !            19: int LP_MAX_N=0,LP_MAX_M=0;
        !            20: int LP_N=0, LP_M=0;
        !            21: double **LP_A=0;
        !            22: double *LP_B=0;
        !            23: double *LP_C=0;
        !            24: double *LP_X=0;
        !            25: int *LP_Basis=0;
        !            26: int *LP_NonBasis=0;
        !            27: double **LP_Q=0;
        !            28: double **LP_R=0;
        !            29: double *LP_t1=0;
        !            30: double *LP_t2=0;
        !            31: double RS_zt=0.0000001;
        !            32:
        !            33:
        !            34: #define basis0(j) (basis[j])
        !            35: #define nonbasis0(j) (nonbasis[j])
        !            36: #define AN0(i,j) (A[nonbasis0(j)][i])
        !            37: #define AB0(i,j) (A[basis0(j)][i])
        !            38: #define CB0(i)   (c[basis0(i)])
        !            39: #define CN0(i)   (c[nonbasis0(i)])
        !            40: #define XB0(i)   (x[basis0(i)])
        !            41: #define XN0(i)   (x[nonbasis0(i)])
        !            42: #define Y0(i)    (t1[i])
        !            43: #define W0(i)    (t2[i])
        !            44: #define D0(i)    (t2[i])
        !            45: #define R0(i,j)  (R[j][i])
        !            46: #define Q0(i,j)  (Q[i][j])
        !            47:
        !            48:
        !            49: /*
        !            50: ** void LP_free_space():
        !            51: **       deallocate space for LP data structures.
        !            52: **       set all LP globals to 0.
        !            53: **
        !            54: */
        !            55: void LP_free_space(){
        !            56:   free_matrix(LP_A);
        !            57:   free_matrix(LP_Q);
        !            58:   free_matrix(LP_R);
        !            59:   free_vector(LP_B);
        !            60:   free_vector(LP_C);
        !            61:   free_vector(LP_X);
        !            62:   free_ivector(LP_Basis);
        !            63:   free_ivector(LP_NonBasis);
        !            64:   free_vector(LP_t1);
        !            65:   free_vector(LP_t2);
        !            66:   LP_M=LP_N=LP_MAX_M=LP_N=0;
        !            67:   LP_A=LP_Q=LP_R=0;
        !            68:   LP_B =LP_C=LP_X=LP_t1=LP_t2=0;
        !            69:   LP_Basis=LP_NonBasis = 0;
        !            70: }
        !            71:
        !            72: /*
        !            73: ** void LP_get_space(int M, int N):
        !            74: **      allocate space for LP data structures.
        !            75: **
        !            76: */
        !            77: void LP_get_space(int M, int N){
        !            78:   if (M>LP_MAX_M || N>LP_MAX_N){
        !            79:     LP_free_space();
        !            80:     LP_A=new_matrix(M,N);
        !            81:     LP_Q=new_matrix(M,M);
        !            82:     LP_R=new_matrix(M,N);
        !            83:     LP_B = new_vector(M);
        !            84:     LP_C = new_vector(N);
        !            85:     LP_X = new_vector(N);
        !            86:     LP_Basis=new_ivector(M);
        !            87:     LP_NonBasis = new_ivector(N-M);
        !            88:     LP_t1=new_vector(N);
        !            89:     LP_t2=new_vector(N);
        !            90:     LP_MAX_M=M;
        !            91:     LP_MAX_N=N;
        !            92:   }
        !            93:   LP_M=M;
        !            94:   LP_N=N;
        !            95: }
        !            96:
        !            97: /*
        !            98: ** void Print_LP():
        !            99: **     print LP data structures to stdout.
        !           100: **
        !           101: */
        !           102: void Print_LP(){
        !           103: int i,j;
        !           104:  fprintf(stdout,"LP_C \n ");
        !           105:  for(i=0;i<LP_N;i++)fprintf(stdout," %f ;", LP_C[i] );
        !           106:  fprintf(stdout,"\nLP_A  | LP_B\n");
        !           107:  for(j=0;j<LP_M;j++) {
        !           108:     for(i=0;i<LP_N;i++) fprintf(stdout," %f ",LP_A(j,i));
        !           109:     fprintf(stdout,"%f \n",LP_B[j]);
        !           110:   }
        !           111:   fprintf(stdout, "LP_X \n ");
        !           112:   for(i=0;i<LP_N;i++) fprintf(stdout," %f ",LP_X[i]);
        !           113:   fprintf(stdout, "\nLP_Basis \n ");
        !           114:   for(i=0;i<LP_M;i++) fprintf(stdout," %d ", LP_Basis[i]);
        !           115:   fprintf(stdout,"\nLP_LP_NonBasis \n ");
        !           116:   for(i=0;i<LP_N-LP_M;i++) fprintf(stdout," %d ",LP_NonBasis[i]);
        !           117:   fprintf(stdout,"\n\n");
        !           118: }
        !           119:
        !           120: /*
        !           121: **
        !           122: **int Rsimp(m,n,A,b,c,x,basis,nonbasis,R,Q,t1,t2):
        !           123: **     revised simplex method (Using Bland's rule)
        !           124: **     and a qr factorization to solve the linear equations
        !           125: **
        !           126: **      Adapted from algorithms presented in
        !           127: **             Linear Approximations and Extensions
        !           128: **             (theory and algorithms)
        !           129: **             Fang & Puthenpura
        !           130: **             Prentice Hall, Engelwood Cliffs NJ (1993)
        !           131: **      and
        !           132: **            Linear Programming
        !           133: **            Chvatal
        !           134: **            Freeman and Company, New York, 1983
        !           135: **
        !           136: **      (developed first in Octave, many thanks to the author)
        !           137: **
        !           138: **
        !           139: **  Solve the problem
        !           140: **       minimize C'x,
        !           141: **       subject to A*x=b,  x>=0
        !           142: **       for x,c,b n-vectors, and A an m,n matrix with full row rank
        !           143: **
        !           144: ** Assumptions:
        !           145: **    A mxn matrix with full row rank.
        !           146: **    b an m matrix.
        !           147: **    c an n-vector.
        !           148: **    x an n-vector holding a basic feasible solution,
        !           149: **    basis m-vector holding indices of the basic variables in x
        !           150: **    nonbasis n-m vector holding the indices not appearing in x.
        !           151: **
        !           152: **  Returns:
        !           153: **      LP_FAIL if algorithm doesn't terminate.
        !           154: **      LP_UNBD if problem is unbounded
        !           155: **      LP_OPT  if optimum found
        !           156: **  efects:
        !           157: **    A,b,c unchanged.
        !           158: **    x basis, nonbasis, hold info describing last basic feasible
        !           159: **                       solution.
        !           160: **    Q,R hold qrdecomp of last basis matrix.
        !           161: **    t1,t2 undefined.
        !           162: **
        !           163: **
        !           164: */
        !           165:
        !           166: int Rsimp(int m, int n, double **A, double *b, double *c,
        !           167:       double *x, int *basis, int *nonbasis,
        !           168:       double **R, double **Q, double *t1, double *t2){
        !           169:  int i,j,k,l,q,qv;
        !           170:  int max_steps=20;
        !           171:  double r,a,at;
        !           172:  int ll;
        !           173:  void GQR(int,int,double**,double**);
        !           174:  max_steps=4*n;
        !           175:
        !           176:  for(k=0; k<=max_steps;k++){
        !           177:    /*
        !           178:    ++ Step 0) load new basis matrix and factor it
        !           179:    */
        !           180:    for(i=0;i<m;i++)for(j=0;j<m;j++)R0(i,j)=AB0(i,j);
        !           181:    GQR(m,m,Q,R);
        !           182:
        !           183:    /*
        !           184:    ++ Step 1) solving system  B'*w=c(basis)
        !           185:    ++      a) forward solve R'*y=c(basis)
        !           186:    */
        !           187:    for(i=0;i<m;i++){
        !           188:      Y0(i)=0.0;
        !           189:      for(j=0;j<i;j++)Y0(i)+=R0(j,i)*Y0(j);
        !           190:      if (R0(i,i)!=0.0) Y0(i)=(CB0(i)-Y0(i))/R0(i,i);
        !           191:      else {
        !           192:        printf("Warning Singular Matrix Found\n");
        !           193:        return LP_FAIL;
        !           194:      }
        !           195:    }
        !           196:    /*
        !           197:    ++      b) find w=Q*y
        !           198:    ++         note: B'*w=(Q*R)'*Q*y= R'*(Q'*Q)*y=R'*y=c(basis)
        !           199:    */
        !           200:    for(i=0;i<m;i++){
        !           201:      W0(i)=0.0;
        !           202:      for(j=0;j<m;j++)W0(i)+=Q0(i,j)*Y0(j);
        !           203:    }
        !           204:
        !           205:    /*
        !           206:    ++ Step 2)find entering variable,
        !           207:    ++ (use lexicographically first variable with negative reduced cost)
        !           208:    */
        !           209:    q=n;
        !           210:    for(i=0;i<n-m;i++){
        !           211:      /* calculate reduced cost */
        !           212:      r=CN0(i);
        !           213:      for(j=0;j<m;j++) r-=W0(j)*AN0(j,i);
        !           214:      if (r<-zero_tol && (q==n || nonbasis0(i)<nonbasis0(q))) q=i;
        !           215:    }
        !           216:
        !           217:    /*
        !           218:    ++ if ratios were all nonnegative current solution is optimal
        !           219:    */
        !           220:    if (q==n){
        !           221:      if (verbose>0) printf("optimal solution found in %d iterations\n",k);
        !           222:      return LP_OPT;
        !           223:    }
        !           224:    /*
        !           225:    ++ Step 3)Calculate translation direction for q entering
        !           226:    ++        by solving system  B*d=-A(:,nonbasis(q));
        !           227:    ++   a) let y=-Q'*A(:,nonbasis(q));
        !           228:    */
        !           229:    for(i=0;i<m;i++){
        !           230:       Y0(i)=0.0;
        !           231:       for(j=0;j<m;j++) Y0(i)-=Q0(j,i)*AN0(j,q);
        !           232:    }
        !           233:
        !           234:    /*
        !           235:    ++  b) back solve Rd=y  (d=R\y)
        !           236:    ++     note B*d= Q*R*d=Q*y=Q*-Q'*A(:nonbasis(q))=-A(:,nonbasis(q))
        !           237:    */
        !           238:    for(i=m-1;i>=0;i--){
        !           239:      D0(i)=0.0;
        !           240:      for(j=m-1;j>=i+1;j--)D0(i)+=R0(i,j)*D0(j);
        !           241:      if (R0(i,i)!=0.0) D0(i)=(Y0(i)-D0(i))/R0(i,i);
        !           242:      else {
        !           243:        printf("Warning Singular Matrix Found\n");
        !           244:        return LP_FAIL;
        !           245:      }
        !           246:    }
        !           247:    /*
        !           248:    ++ Step 4 Choose leaving variable
        !           249:    ++     (first variable to become negative, by moving in direction D)
        !           250:    ++     (if none become negative, then objective function unbounded)
        !           251:    */
        !           252:    a=0;
        !           253:    l=-1;
        !           254:    for(i=0;i<m;i++){
        !           255:      if (D0(i)<-zero_tol){
        !           256:         at=-1*XB0(i)/D0(i);
        !           257:         if (l==-1 || at<a){ a=at; l=i;}
        !           258:      }
        !           259:    }
        !           260:    if (l==-1){
        !           261:      if (verbose>0){
        !           262:          printf("Objective function Unbounded (%d iterations)\n",k);
        !           263:      }
        !           264:      return LP_UNBD;
        !           265:    }
        !           266:    /*
        !           267:    ++ Step 5) Update solution and basis data
        !           268:    */
        !           269:    XN0(q)=a;
        !           270:    for(j=0;j<m;j++) XB0(j)+=a*D0(j);
        !           271:    XB0(l)=0.0;             /* enforce strict zeroness of nonbasis variables */
        !           272:    qv=nonbasis0(q);
        !           273:    nonbasis0(q)=basis0(l);
        !           274:    basis0(l)=qv;
        !           275:  }
        !           276:  if (verbose>=0){
        !           277:    printf("Simplex Algorithm did not Terminate in %d iterations\n",k);
        !           278:  }
        !           279:  return LP_FAIL;
        !           280: }
        !           281:
        !           282:
        !           283: /*
        !           284: **void GQR(int r, int c, double **Q, double **R):
        !           285: **  Use givens rotations on R to bring it into triangular form.
        !           286: **  Store orthogonal matrix needed to bring R to triangular form in Q.
        !           287: **  Assume R is an rxc matrix and Q is rxr.
        !           288: **  (Question: is r>=c needed ?)
        !           289: **
        !           290: */
        !           291: void GQR(int r, int c, double **Q, double **R){
        !           292:      int i,j,k;
        !           293:      double s,s1,s2;
        !           294:      double t1,t2;
        !           295:
        !           296:      for(i=0;i<r;i++){
        !           297:         for(k=0;k<r;k++)Q0(i,k)=0.0;
        !           298:         Q0(i,i)=1.0;
        !           299:      }
        !           300:
        !           301:      for (i=0;i<c;i++)
        !           302:        for (k=i+1;k<r;k++)
        !           303:          /* performing givens rotations to zero A[k][i] */
        !           304:          if (R0(k,i)!=0){
        !           305:            s=sqrt(R0(i,i)*R0(i,i)+R0(k,i)*R0(k,i));
        !           306:            s1=R0(i,i)/s;
        !           307:            s2=R0(k,i)/s;
        !           308:            for(j=0;j<c;j++) {
        !           309:              t1=R0(i,j);
        !           310:              t2=R0(k,j);
        !           311:              R0(i,j)=s1*t1+s2*t2;
        !           312:              R0(k,j)=-s2*t1+s1*t2;
        !           313:            }
        !           314:            /* actually doing givens row rotations on  Q */
        !           315:            for(j=0;j<r;j++){
        !           316:              t1=Q0(j,i);
        !           317:              t2=Q0(j,k);
        !           318:              Q0(j,i)=s1*t1+s2*t2;
        !           319:              Q0(j,k)=-s2*t1+s1*t2;
        !           320:           }
        !           321:         }
        !           322:
        !           323: }
        !           324:
        !           325:
        !           326:
        !           327:
        !           328:
        !           329:

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>