Annotation of OpenXM/src/Ti/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>