main(int argc, char **argv) { int m; /* number of constraints */ int n; /* number of variables */ int nz; /* number of nonzeros in sparse constraint matrix */ int *ia; /* array row indices */ int *ka; /* array of indices into ia and a */ double *a; /* array of nonzeros in the constraint matrix */ double *b; /* right-hand side */ double *c; /* objective coefficients */ double *c2; /* objective coefficients */ int *basics; /* list of basic variable indices */ int *nonbasics; /* list of non-basic variable indices */ int *basicflag; /* neg if nonbasic, pos if basic */ int *freevars; /* boolean indicator of free variables */ double **X, **Y, **Z, **BETA0, **BETAhat, **TMP; time_t start_time, end_time; double elapsed_time; int knum = 100; int offset = atoi(argv[2]); int counter = offset * GAUSS_OFFSET ; int counter2 = offset * IDX_OFFSET ; int i, j, k, i1, i2, j1, j2, n1, n2, d1, d2, b_idx, n_idx; n1 = 33; n2 = 34; d1 = 141; d2 = atoi(argv[1]); FILE* file = fopen("rng_gauss.csv", "r"); i = 0; j = 0; double num = 0; double rng_gauss[LEN_GAUSS]; while(fscanf(file, "%lf,", &num) > 0) { rng_gauss[i++] = num; if (i>=LEN_GAUSS) break; } fclose(file); int num2 = 0; int rng_i[LEN_IDX]; int rng_j[LEN_IDX]; i = 0; file = fopen("rng_idx.csv", "r"); while(fscanf(file, "%d,", &num2) > 0){ rng_i[i] = (num2-1)/d2; rng_j[i] = (num2-1)%d2; i++; if (i>=LEN_IDX) break; } fclose(file); m = n1*d2 + n1*n2; n = 2*d1*d2 + n1*d2 + 2*n1*n2; nz = 2*n1*d1*d2 + d2*n1 + n2*d2*n1 + 2*n1*n2; CALLOC( a, nz, double ); CALLOC( ia, nz, int ); CALLOC( ka, n+1, int ); CALLOC( b, m, double ); CALLOC( c, n, double ); CALLOC( c2, n, double ); CALLOC( basics, m, int ); CALLOC(nonbasics, n-m, int ); CALLOC(basicflag, n, int ); CALLOC(freevars, n, int ); CALLOC( BETA0, d1, double *); for (i=0; i<d1; i++) { CALLOC( BETA0[i], d2, double ); } CALLOC( BETAhat, d1, double *); for (i=0; i<d1; i++) { CALLOC( BETAhat[i], d2, double ); } CALLOC( X, n1, double *); for (i=0; i<n1; i++) { CALLOC( X[i], d1, double); } CALLOC( Z, n2, double *); for (i=0; i<n2; i++) { CALLOC( Z[i], d2, double); } CALLOC( Y, n1, double *); for (i=0; i<n1; i++) { CALLOC( Y[i], n2, double); } CALLOC( TMP, n1, double *); for (i=0; i<n1; i++) { CALLOC( TMP[i], d2, double ); } int kk; for (kk=0; kk<knum; kk++) { j1 = rng_i[counter2]; j2 = rng_j[counter2]; counter2++; if(j1<d1 & j2<d2){ if (BETA0[j1][j2]==0){ BETA0[j1][j2] = 1.; } else{ kk--; } if(counter2>=LEN_IDX) counter2 = 0; } } for (j1=0; j1<d1; j1++) { for (i1=0; i1<n1; i1++) { X[i1][j1] = rng_gauss[counter++]; if(counter>=LEN_GAUSS) counter = 0; } } for (j2=0; j2<d2; j2++) { for (i2=0; i2<n2; i2++) { Z[i2][j2] = rng_gauss[counter++]; if(counter>=LEN_GAUSS) counter = 0; } } for (i1=0; i1<n1; i1++) { for (j2=0; j2<d2; j2++) { TMP[i1][j2] = 0; for (j=0; j<d1; j++) { TMP[i1][j2] += X[i1][j]*BETA0[j][j2]; } } } for (i1=0; i1<n1; i1++) { for (j2=0; j2<n2; j2++) { Y[i1][j2] = 0; for (j=0; j<d2; j++) { Y[i1][j2] += TMP[i1][j]*Z[j2][j]; } } } time(&start_time); /***************************************************************** * Structure of the problem: * * + - + - * beta beta C eps eps * * zeta = -e^T -e^T * zetabar = -mu e^T -mu e^T * --------------------------------------------------------------- * X -X -I = 0 (n1) * X -X -I = 0 (n1) * . . . * X -X -I = 0 (n1) * * zI zI zI I -I = y_1 (n1) * zI zI zI I -I = y_2 (n1) * . . . * zI zI zI I -I = y_n2 (n1) * * NOTE: C is free * ***************************************************************/ k=0; for (j2=0; j2<d2; j2++) { for (j1=0; j1<d1; j1++) { j = d1*j2 + j1; ka[j] = k; for (i1=0; i1<n1; i1++) { a[k] = X[i1][j1]; ia[k] = j2*n1 + i1; k++; } c [j] = 0; c2[j] = -1; } } for (j2=0; j2<d2; j2++) { for (j1=0; j1<d1; j1++) { j = d1*d2 + d1*j2 + j1; ka[j] = k; for (i1=0; i1<n1; i1++) { a[k] = -X[i1][j1]; ia[k] = j2*n1 + i1; k++; } c [j] = 0; c2[j] = -1; } } for (j2=0; j2<d2; j2++) { for (i1=0; i1<n1; i1++) { j = 2*d1*d2 + j2*n1 + i1; freevars[j] = 1; ka[j] = k; i = j2*n1 + i1; a[k] = -1; ia[k] = i; k++; for (i2=0; i2<n2; i2++) { i = d2*n1 + i2*n1 + i1; a[k] = Z[i2][j2]; ia[k] = i; k++; } } } i=n1*d2; for (j=2*d1*d2+n1*d2; j<2*d1*d2+n1*d2+n1*n2; j++) { ka[j] = k; a[k] = 1; ia[k] = i; k++; i++; c [j] = -1; c2[j] = 0; } i=n1*d2; for (j=2*d1*d2+n1*d2+n1*n2; j<2*d1*d2+n1*d2+2*n1*n2; j++) { ka[j] = k; a[k] = -1; ia[k] = i; k++; i++; c [j] = -1; c2[j] = 0; } ka[n] = k; for (i=0; i<n1*d2; i++) { b[i] = 0; } for (i2=0; i2<n2; i2++) { for (i1=0; i1<n1; i1++) { i = n1*d2 + i2*n1 + i1; b[i] = Y[i1][i2]; } } b_idx = 0; n_idx = 0; for (j=0; j<2*d1*d2; j++) { nonbasics[n_idx] = j; basicflag[j] = -n_idx-1; n_idx++; } for (j=2*d1*d2; j<2*d1*d2+n1*d2; j++) { basics[b_idx] = j; basicflag[j] = b_idx; b_idx++; } for (i=0; i<n1*n2; i++) { j = 2*d1*d2+n1*d2+i; if (b[n1*d2 + i] >= 0) { basics[b_idx] = j; basicflag[j] = b_idx; b_idx++; } else { nonbasics[n_idx] = j; basicflag[j] = -n_idx-1; n_idx++; } } for (i=0; i<n1*n2; i++) { j = 2*d1*d2+n1*d2+n1*n2+i; if (b[n1*d2 + i] < 0) { basics[b_idx] = j; basicflag[j] = b_idx; b_idx++; } else { nonbasics[n_idx] = j; basicflag[j] = -n_idx-1; n_idx++; } } solver2(m,n,nz,ia,ka,a,b,c,c2,0,basics,nonbasics,basicflag,freevars,d1,d2,BETAhat); time(&end_time); elapsed_time = difftime(end_time,start_time); /*printf("==================================================\n");*/ double betahatsum = 0.0; /*printf("BETAhat: \n");*/ for (i1=0; i1<d1; i1++){ for (i2=0; i2<d2; i2++){ /* if(ABS(BETAhat[i1][i2])>EPS0) printf("[%d,%d]: %6.2f, ",i1,i2,BETAhat[i1][i2]);*/ betahatsum = betahatsum + ABS(BETAhat[i1][i2]); } } /*printf("Betahat sum: %f\n", betahatsum);*/ double maxerror = 0.0; double l1error = 0.0; int happy = 1; double tmp = 0.; double maxBETA0 = 0.0; for (j1=0; j1<d1; j1++) { for (j2=0; j2<d2; j2++) { if (ABS(BETA0[j1][j2]) > maxBETA0) { maxBETA0 = ABS(BETA0[j1][j2]); } } } for (j1=0; j1<d1; j1++) { for (j2=0; j2<d2; j2++) { tmp = ABS(BETA0[j1][j2]-BETAhat[j1][j2]); l1error = l1error + tmp; if (tmp > maxerror) maxerror = tmp; if (tmp > 1e-5*maxBETA0) { happy = 0; } } } /* printf("Max error: %f\n", maxerror); printf("L1 error: %f\n", l1error); if (happy) { printf("happy: "); } else { printf("unhappy: "); } printf("Solution time (seconds): %0.2lf \n", elapsed_time);*/ printf("%d, %f, %f, %f\n",d2 , elapsed_time, maxerror, l1error); lu_clo(); for (i=0; i<d1; i++){ FREE(BETA0[i]); FREE(BETAhat[i]); } for (i=0; i<n1; i++){ FREE(X[i]); FREE(Y[i]); FREE(TMP[i]); } for (i=0; i<n2; i++){ FREE(Z[i]); } FREE(BETA0); FREE(BETAhat); FREE(X); FREE(Y); FREE(Z); FREE(TMP); FREE(a); FREE(ia); FREE(ka); FREE(b); FREE(c); FREE(c2); FREE(basicflag); FREE(freevars); return 0; }
int solver2( int m, /* number of constraints */ int N, /* number of variables */ int nz, /* number of nonzeros in sparse constraint matrix */ int *ia, /* array row indices */ int *ka, /* array of indices into ia and a */ double *a, /* array of nonzeros in the constraint matrix */ double *b, /* right-hand side */ double *c, /* objective coefficients */ double *c2, /* objective coefficients */ double f, /* objective function shift */ int *basics, int *nonbasics, int *basicflag, int *freevars, int d1, int d2, double **BETAhat ) { double *x_B; /* primal basics */ double *y_N; /* dual nonbasics */ double *xbar_B; /* primal basic perturbation */ double *ybar_N; /* dual nonbasic perturbation */ double *dy_N; /* dual basics step direction - values (sparse) */ int *idy_N; /* dual basics step direction - row indices */ int ndy_N; /* number of nonz in dy_N */ double *dx_B; /* primal basics step direction - values (sparse) */ int *idx_B; /* primal basics step direction - row indices */ int ndx_B; /* number of nonz in dx_B */ double *at; /* sparse data structure for A^T */ int *iat; int *kat; int col_in; /* entering column; index in 'nonbasics' */ int col_out; /* leaving column; index in 'basics' */ int iter = 0; /* number of iterations */ int i,j,k,n,v=0, j1,j2,ii; double s, t, sbar, tbar, mu=HUGE_VAL, old_mu, primal_obj; double *vec; int *ivec; int nvec; int status=0; int from_scratch; /******************************************************************* * For convenience, we put... *******************************************************************/ int n0 = d1*d2; n = N-m; /******************************************************************* * Read in the Data and initialize the common memory sites. *******************************************************************/ CALLOC( x_B, m, double ); CALLOC( xbar_B, m, double ); CALLOC( dx_B, m, double ); CALLOC( y_N, n, double ); CALLOC( ybar_N, n, double ); CALLOC( dy_N, n, double ); CALLOC( vec, N, double ); CALLOC( idx_B, m, int ); CALLOC( idy_N, n, int ); CALLOC( ivec, N, int ); CALLOC( at, nz, double ); CALLOC( iat, nz, int ); CALLOC( kat, m+1, int ); /**************************************************************** * Initialization. * ****************************************************************/ atnum(m,N,ka,ia,a,kat,iat,at); lufac( m, ka, ia, a, basics, 0); for (j=0; j<n; j++) { y_N[j] = 0; } nvec = 0; for (i=0; i<m; i++) { if (c[basics[i]] != 0.0) { vec[nvec] = c[basics[i]]; ivec[nvec] = i; nvec++; } } btsolve( m, vec, ivec, &nvec ); Nt_times_y( N, at, iat, kat, basicflag, vec, ivec, nvec, dy_N, idy_N, &ndy_N ); for (k=0; k<ndy_N; k++) { y_N[idy_N[k]] = dy_N[k]; } for (j=0; j<n; j++) { y_N[j] -= c[nonbasics[j]]; } for (j=0; j<n; j++) { ybar_N[j] = 0; } nvec = 0; for (i=0; i<m; i++) { if (c2[basics[i]] != 0.0) { vec[nvec] = c2[basics[i]]; ivec[nvec] = i; nvec++; } } btsolve( m, vec, ivec, &nvec ); Nt_times_y( N, at, iat, kat, basicflag, vec, ivec, nvec, dy_N, idy_N, &ndy_N ); for (k=0; k<ndy_N; k++) { ybar_N[idy_N[k]] = dy_N[k]; } for (j=0; j<n; j++) { ybar_N[j] -= c2[nonbasics[j]]; if (ybar_N[j] < 0) printf("error: ybar_N[%d] = %e \n", j, ybar_N[j]); } for (i=0; i<m; i++) { x_B[i] = 0; xbar_B[i] = 0; } nvec = 0; for (i=0; i<m; i++) { if ( b[i] != 0.0 ) { vec[nvec] = b[i]; ivec[nvec] = i; nvec++; } } bsolve( m, vec, ivec, &nvec ); for (i=0; i<nvec; i++) { x_B[ivec[i]] = vec[i]; if (vec[i] < 0) printf("error: x_B[%d] = %e \n", i, vec[i]); } /* printf ("m = %d,n = %d,nz = %d\n",m,N,nz); printf( "---------------------------------------------------------------------------\n" " | Primal | | arithmetic \n" " Iter | Obj Value | mu | nonz(L) nonz(U) operations \n" "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\n" );*/ /**************************************************************** * Main loop * ****************************************************************/ for (iter=0; iter<MAX_ITER; iter++) { /************************************************************* * STEP 1: Find mu * *************************************************************/ old_mu = mu; mu = -HUGE_VAL; col_in = -1; for (j=0; j<n; j++) { if (ybar_N[j] > EPS2) { if ( mu < -y_N[j]/ybar_N[j] ) { mu = -y_N[j]/ybar_N[j]; col_in = j; } } } col_out = -1; for (i=0; i<m; i++) { if (freevars[basics[i]] == 0) { if (xbar_B[i] > EPS2) { if ( mu < -x_B[i]/xbar_B[i] ) { mu = -x_B[i]/xbar_B[i]; col_out = i; col_in = -1; } } } } /************************************************************* * STEP 0: Record current portfolio * *************************************************************/ primal_obj = sdotprod(c,x_B,basics,m) + f; if ( mu <= EPS3 || primal_obj > -EPS0) { /* OPTIMAL */ for (j1=0; j1<d1; j1++) { for (j2=0; j2<d2; j2++) { BETAhat[j1][j2] = 0; } } for (i=0; i<m; i++) { if (basics[i] < n0 && x_B[i] > EPS0) { ii = basics[i]; j1 = ii%d1; j2 = ii/d1; BETAhat[j1][j2] = x_B[i]; } else if (basics[i] < 2*n0 && x_B[i] > EPS0) { ii = basics[i]-n0; j1 = ii%d1; j2 = ii/d1; BETAhat[j1][j2] = -x_B[i]; } } for (j1=0; j1<d1; j1++) { for (j2=0; j2<d2; j2++) { if (ABS(BETAhat[j1][j2]) > 1e-5) { } } } status = 0; break; } if ( col_out >= 0 ) { /************************************************************* * -1 T * * STEP 2: Compute dy = -(B N) e * * N i * * where i = col_out * *************************************************************/ vec[0] = -1.0; ivec[0] = col_out; nvec = 1; btsolve( m, vec, ivec, &nvec ); Nt_times_y( N, at, iat, kat, basicflag, vec, ivec, nvec, dy_N, idy_N, &ndy_N ); /************************************************************* * STEP 3: Ratio test to find entering column * *************************************************************/ col_in = ratio_test2( dy_N, idy_N, ndy_N, y_N, ybar_N, mu ); if (col_in == -1) { /* INFEASIBLE*/ status = 2; printf("infeasible \n"); break; } /************************************************************* * -1 * * STEP 4: Compute dx = B N e * * B j * * * *************************************************************/ j = nonbasics[col_in]; for (i=0, k=ka[j]; k<ka[j+1]; i++, k++) { dx_B[i] = a[k]; idx_B[i] = ia[k]; } ndx_B = i; bsolve( m, dx_B, idx_B, &ndx_B ); } else { /************************************************************* * -1 * * STEP 2: Compute dx = B N e * * B j * *************************************************************/ j = nonbasics[col_in]; for (i=0, k=ka[j]; k<ka[j+1]; i++, k++) { dx_B[i] = a[k]; idx_B[i] = ia[k]; } ndx_B = i; bsolve( m, dx_B, idx_B, &ndx_B ); /************************************************************* * STEP 3: Ratio test to find leaving column * *************************************************************/ col_out = ratio_test( dx_B, idx_B, ndx_B, x_B, xbar_B, basics, freevars, mu ); if (col_out == -1) { /* UNBOUNDED */ status = 1; printf("unbounded \n"); break; } /************************************************************* * -1 T * * STEP 4: Compute dy = -(B N) e * * N i * * * *************************************************************/ vec[0] = -1.0; ivec[0] = col_out; nvec = 1; btsolve( m, vec, ivec, &nvec ); Nt_times_y( N, at, iat, kat, basicflag, vec, ivec, nvec, dy_N, idy_N, &ndy_N ); } /************************************************************* * * * STEP 5: Put t = x /dx * * i i * * _ _ * * t = x /dx * * i i * * s = y /dy * * j j * * _ _ * * s = y /dy * * j j * *************************************************************/ for (k=0; k<ndx_B; k++) if (idx_B[k] == col_out) break; t = x_B[col_out]/dx_B[k]; tbar = xbar_B[col_out]/dx_B[k]; for (k=0; k<ndy_N; k++) if (idy_N[k] == col_in) break; s = y_N[col_in]/dy_N[k]; sbar = ybar_N[col_in]/dy_N[k]; /************************************************************* * _ _ _ * * STEP 7: Set y = y - s dy y = y - s dy * * N N N N N N * * _ _ * * y = s y = s * * i i * * _ _ _ * * x = x - t dx x = x - t dx * * B B B B B B * * _ _ * * x = t x = t * * j j * *************************************************************/ for (k=0; k<ndy_N; k++) { j = idy_N[k]; y_N[j] -= s *dy_N[k]; ybar_N[j] -= sbar*dy_N[k]; } y_N[col_in] = s; ybar_N[col_in] = sbar; for (k=0; k<ndx_B; k++) { i = idx_B[k]; x_B[i] -= t *dx_B[k]; xbar_B[i] -= tbar*dx_B[k]; } x_B[col_out] = t; xbar_B[col_out] = tbar; /************************************************************* * STEP 8: Update basis * *************************************************************/ i = basics[col_out]; j = nonbasics[col_in]; basics[col_out] = j; nonbasics[col_in] = i; basicflag[i] = -col_in-1; basicflag[j] = col_out; /************************************************************* * STEP 9: Refactor basis and print statistics * *************************************************************/ from_scratch = refactor( m, ka, ia, a, basics, col_out, v); if (from_scratch) { primal_obj = sdotprod(c,x_B,basics,m) + f; /* printf("%8d %14.7e %9.2e \n", iter, high(primal_obj), high(mu)); fflush(stdout);*/ } } primal_obj = sdotprod(c,x_B,basics,m) + f; /**************************************************************** * Transcribe solution to x vector and dual solution to y * ****************************************************************/ /**************************************************************** * Split out slack variables and shift dual variables. ****************************************************************/ /**************************************************************** * Free work space * ****************************************************************/ Nt_times_y(-1, at, iat, kat, basicflag, vec, ivec, nvec, dy_N, idy_N, &ndy_N); FREE(at); FREE(iat); FREE(xbar_B); FREE(kat); FREE(ybar_N); lu_clo(); btsolve(0, vec, ivec, &nvec); bsolve(0, vec, ivec, &nvec); FREE( vec ); FREE( ivec ); FREE( x_B ); FREE( y_N ); FREE( dx_B ); FREE(idx_B ); FREE( dy_N ); FREE(idy_N ); FREE( nonbasics ); FREE( basics ); return status; } /* End of solver */
void solver20( int m, /* number of constraints */ int n, /* number of variables */ int nz, /* number of nonzeros in sparse constraint matrix */ int *ia, /* array row indices */ int *ka, /* array of indices into ia and a */ double *a, /* array of nonzeros in the constraint matrix */ double *b, /* right-hand side */ double *c /* objective coefficients */ ) { /*structure of the solver*/ int *basics; int *nonbasics; int *basicflag; double *x_B; /* primal basics */ double *y_N; /* dual nonbasics */ double *xbar_B; /* primal basic perturbation */ double *ybar_N; /* dual nonbasic perturbation*/ double *dy_N; /* dual basics step direction - values (sparse) */ int *idy_N; /* dual basics step direction - row indices */ int ndy_N=0; /* number of nonz in dy_N */ double *dx_B; /* primal basics step direction - values (sparse) */ int *idx_B; /* primal basics step direction - row indices */ int ndx_B; /* number of nonz in dx_B */ double *at; /* sparse data structure for a^t */ int *iat; int *kat; int col_in; /* entering column; index in 'nonbasics' */ int col_out; /* leaving column; index in 'basics' */ int iter = 0; /* number of iterations */ int i,j,k,v=0; double s, t, sbar, tbar, mu=HUGE_VAL; double *vec; int *ivec; int nvec; int N; N=m+n; /******************************************************************* * read in the data and initialize the common memory sites. *******************************************************************/ //add the slack variables i = 0; k = ka[n]; for (j=n; j<N; j++) { a[k] = 1.0; ia[k] = i; i++; k++; ka[j+1] = k; } nz = k; MALLOC( x_B, m, double ); MALLOC( xbar_B, m, double ); MALLOC( dx_B, m, double ); MALLOC( y_N, n, double ); MALLOC( ybar_N, n, double ); MALLOC( dy_N, n, double ); MALLOC( vec, N, double ); MALLOC( ivec, N, int ); MALLOC( idx_B, m, int ); MALLOC( idy_N, n, int ); MALLOC( at, nz, double ); MALLOC( iat, nz, int ); MALLOC( kat, m+1, int ); MALLOC( basics, m, int ); MALLOC( nonbasics, n, int ); MALLOC( basicflag, N, int ); CALLOC( x, N, double ); /**************************************************************** * initialization. * ****************************************************************/ atnum(m,N,ka,ia,a,kat,iat,at); for (j=0; j<n; j++) { nonbasics[j] = j; basicflag[j] = -j-1; y_N[j] = -c[j]; ybar_N[j] = 1; } for (i=0; i<m; i++) { basics[i] = n+i; basicflag[n+i] = i; x_B[i] = b[i]; xbar_B[i] = 1; } lufac( m, ka, ia, a, basics, 0 ); for (iter=0; iter<MAX_ITER; iter++) { /************************************************************* * step 1: find mu * *************************************************************/ mu = -HUGE_VAL; col_in = -1; for (j=0; j<n; j++) { if (ybar_N[j] > EPS2) { if ( mu < -y_N[j]/ybar_N[j] ) { mu = -y_N[j]/ybar_N[j]; col_in = j; } } } col_out = -1; for (i=0; i<m; i++) { if (xbar_B[i] > EPS2) { if ( mu < -x_B[i]/xbar_B[i] ) { mu = -x_B[i]/xbar_B[i]; col_out = i; col_in = -1; } } } if ( mu <= lambda0 ) { /* optimal */ status0=0; break; } /************************************************************* * -1 t * * step 2: compute dy = -(b n) e * * n i * * where i = col_out * *************************************************************/ if ( col_out >= 0 ) { vec[0] = -1.0; ivec[0] = col_out; nvec = 1; btsolve( m, vec, ivec, &nvec ); Nt_times_y( N, at, iat, kat, basicflag, vec, ivec, nvec, dy_N, idy_N, &ndy_N ); col_in = ratio_test0( dy_N, idy_N, ndy_N, y_N, ybar_N,mu ); /************************************************************* * STEP 3: Ratio test to find entering column * *************************************************************/ if (col_in == -1) { /* infeasible */ status0 = 1; break; } /************************************************************* * -1 * * step 4: compute dx = b n e * * b j * * * *************************************************************/ j = nonbasics[col_in]; for (i=0, k=ka[j]; k<ka[j+1]; i++, k++) { dx_B[i] = a[k]; idx_B[i] = ia[k]; } ndx_B = i; bsolve( m, dx_B, idx_B, &ndx_B ); } else { /************************************************************* * -1 * * STEP 2: Compute dx = B N e * * B j * *************************************************************/ j = nonbasics[col_in]; for (i=0, k=ka[j]; k<ka[j+1]; i++, k++) { dx_B[i] = a[k]; idx_B[i] = ia[k]; } ndx_B = i; bsolve( m, dx_B, idx_B, &ndx_B ); /************************************************************* * STEP 3: Ratio test to find leaving column * *************************************************************/ col_out = ratio_test0( dx_B, idx_B, ndx_B, x_B, xbar_B, mu ); if (col_out == -1) { /* UNBOUNDED */ status0 = 2; break; } /************************************************************* * -1 T * * STEP 4: Compute dy = -(B N) e * * N i * * * *************************************************************/ vec[0] = -1.0; ivec[0] = col_out; nvec = 1; btsolve( m, vec, ivec, &nvec ); Nt_times_y( N, at, iat, kat, basicflag, vec, ivec, nvec, dy_N, idy_N, &ndy_N ); } /************************************************************* * * * step 5: put t = x /dx * * i i * * _ _ * * t = x /dx * * i i * * s = y /dy * * j j * * _ _ * * s = y /dy * * j j * *************************************************************/ for (k=0; k<ndx_B; k++) if (idx_B[k] == col_out) break; t = x_B[col_out]/dx_B[k]; tbar = xbar_B[col_out]/dx_B[k]; for (k=0; k<ndy_N; k++) if (idy_N[k] == col_in) break; s = y_N[col_in]/dy_N[k]; sbar = ybar_N[col_in]/dy_N[k]; /************************************************************* * _ _ _ * * step 7: set y = y - s dy y = y - s dy * * n n n n n n * * _ _ * * y = s y = s * * i i * * _ _ _ * * x = x - t dx x = x - t dx * * b b b b b b * * _ _ * * x = t x = t * * j j * *************************************************************/ for (k=0; k<ndy_N; k++) { j = idy_N[k]; y_N[j] -= s *dy_N[k]; ybar_N[j] -= sbar*dy_N[k]; } y_N[col_in] = s; ybar_N[col_in] = sbar; for (k=0; k<ndx_B; k++) { i = idx_B[k]; x_B[i] -= t *dx_B[k]; xbar_B[i] -= tbar*dx_B[k]; } x_B[col_out] = t; xbar_B[col_out] = tbar; /************************************************************* * step 8: update basis * *************************************************************/ i = basics[col_out]; j = nonbasics[col_in]; basics[col_out] = j; nonbasics[col_in] = i; basicflag[i] = -col_in-1; basicflag[j] = col_out; /************************************************************* * step 9: refactor basis and print statistics * *************************************************************/ refactor( m, ka, ia, a, basics, col_out, v ); } for (i=0; i<m; i++) { x[basics[i]] = x_B[i]; } if(iter>=1){ Nt_times_y( -1, at, iat, kat, basicflag, vec, ivec, nvec, dy_N, idy_N, &ndy_N ); } /**************************************************************** * free work space * ****************************************************************/ FREE( vec ); FREE( ivec ); FREE( x_B ); FREE( y_N ); FREE( dx_B ); FREE(idx_B ); FREE( dy_N ); FREE(idy_N ); FREE(xbar_B); FREE(ybar_N); FREE( nonbasics ); FREE( basics ); FREE(at); FREE(iat); FREE(basicflag); FREE(kat); if(iter>=1){ lu_clo(); btsolve(0, vec, ivec, &nvec); bsolve(0, vec, ivec, &nvec); } }