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); } }
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 */
int solver(int m,int n,int nz,int *iA, int *kA, double *A, double *b, double *c, double f, double *x, double *y, double *w, double *z) { double *dx, *dw, *dy, *dz; /* step directions */ double *fx, *fy, *gx, *gy; double phi, psi, dphi, dpsi; double *rho, *sigma, normr, norms; /* infeasibilites */ double *D, *E; /* diagonal matrices */ double gamma, beta, delta, mu, theta; /* parameters */ double *At; /* arrays for A^T */ int *iAt, *kAt; int i,j,iter,v=1,status=5; double primal_obj, dual_obj; /******************************************************************* * Allocate memory for arrays. *******************************************************************/ MALLOC( dx, n, double ); MALLOC( dw, m, double ); MALLOC( dy, m, double ); MALLOC( dz, n, double ); MALLOC( rho, m, double ); MALLOC( sigma, n, double ); MALLOC( D, n, double ); MALLOC( E, m, double ); MALLOC( fx, n, double ); MALLOC( fy, m, double ); MALLOC( gx, n, double ); MALLOC( gy, m, double ); MALLOC( At, nz, double ); MALLOC( iAt, nz, int ); MALLOC( kAt, m+1, int ); /**************************************************************** * Initialization. * ****************************************************************/ for (j=0; j<n; j++) { x[j] = 1.0; z[j] = 1.0; } for (i=0; i<m; i++) { w[i] = 1.0; y[i] = 1.0; } phi = 1.0; psi = 1.0; atnum(m,n,kA,iA,A,kAt,iAt,At); /**************************************************************** * Display Banner. ****************************************************************/ printf ("m = %d,n = %d,nz = %d\n",m,n,nz); printf( "--------------------------------------------------------------------------\n" " | Primal | Dual | |\n" " Iter | Obj Value Infeas | Obj Value Infeas | mu |\n" "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \n" ); fflush(stdout); /**************************************************************** * Iteration. ****************************************************************/ beta = 0.80; delta = 2*(1-beta); for (iter=0; iter<MAX_ITER; iter++) { /************************************************************* * STEP 1: Compute mu. *************************************************************/ mu = (dotprod(z,x,n)+dotprod(w,y,m)+phi*psi) / (n+m+1); /************************************************************* * STEP 1: Compute primal and dual objective function values. *************************************************************/ primal_obj = dotprod(c,x,n); dual_obj = dotprod(b,y,m); /************************************************************* * STEP 2: Check stopping rule. *************************************************************/ if ( mu < EPS ) { if ( phi > EPS ) { status = 0; break; /* OPTIMAL */ } else if ( dual_obj < 0.0) { status = 2; break; /* PRIMAL INFEASIBLE */ } else if ( primal_obj > 0.0) { status = 4; break; /* DUAL INFEASIBLE */ } else { status = 7; /* NUMERICAL PROBLEM */ break; } } /************************************************************* * STEP 3: Compute infeasibilities. *************************************************************/ smx(m,n,A,kA,iA,x,rho); for (i=0; i<m; i++) { rho[i] = rho[i] - b[i]*phi + w[i]; } normr = sqrt( dotprod(rho,rho,m) )/phi; for (i=0; i<m; i++) { rho[i] = -(1-delta)*rho[i] + w[i] - delta*mu/y[i]; } smx(n,m,At,kAt,iAt,y,sigma); for (j=0; j<n; j++) { sigma[j] = -sigma[j] + c[j]*phi + z[j]; } norms = sqrt( dotprod(sigma,sigma,n) )/phi; for (j=0; j<n; j++) { sigma[j] = -(1-delta)*sigma[j] + z[j] - delta*mu/x[j]; } gamma = -(1-delta)*(dual_obj - primal_obj + psi) + psi - delta*mu/phi; /************************************************************* * Print statistics. *************************************************************/ printf("%8d %14.7e %8.1e %14.7e %8.1e %8.1e \n", iter, high(primal_obj/phi+f), high(normr), high(dual_obj/phi+f), high(norms), high(mu) ); fflush(stdout); /************************************************************* * STEP 4: Compute step directions. *************************************************************/ for (j=0; j<n; j++) { D[j] = z[j]/x[j]; } for (i=0; i<m; i++) { E[i] = w[i]/y[i]; } ldltfac(n, m, kAt, iAt, At, E, D, kA, iA, A, v); for (j=0; j<n; j++) { fx[j] = -sigma[j]; } for (i=0; i<m; i++) { fy[i] = rho[i]; } forwardbackward(E, D, fy, fx); for (j=0; j<n; j++) { gx[j] = -c[j]; } for (i=0; i<m; i++) { gy[i] = -b[i]; } forwardbackward(E, D, gy, gx); dphi = (dotprod(c,fx,n)-dotprod(b,fy,m)+gamma)/ (dotprod(c,gx,n)-dotprod(b,gy,m)-psi/phi); for (j=0; j<n; j++) { dx[j] = fx[j] - gx[j]*dphi; } for (i=0; i<m; i++) { dy[i] = fy[i] - gy[i]*dphi; } for (j=0; j<n; j++) { dz[j] = delta*mu/x[j] - z[j] - D[j]*dx[j]; } for (i=0; i<m; i++) { dw[i] = delta*mu/y[i] - w[i] - E[i]*dy[i]; } dpsi = delta*mu/phi - psi - (psi/phi)*dphi; /************************************************************* * STEP 5: Compute step length. *************************************************************/ theta = 1.0; for (j=0; j<n; j++) { theta = MIN(theta, linesearch(x[j],z[j],dx[j],dz[j],beta,delta,mu)); } for (i=0; i<m; i++) { theta = MIN(theta,linesearch(y[i],w[i],dy[i],dw[i],beta,delta,mu)); } theta = MIN(theta,linesearch(phi,psi,dphi,dpsi,beta,delta,mu)); /* if (theta < 4*beta/(n+m+1)) { printf("ratio = %10.3e \n", theta*(n+m+1)/(4*beta)); status = 7; break; } */ if (theta < 1.0) theta *= 0.9999; /************************************************************* * STEP 6: Step to new point *************************************************************/ for (j=0; j<n; j++) { x[j] = x[j] + theta*dx[j]; z[j] = z[j] + theta*dz[j]; } for (i=0; i<m; i++) { y[i] = y[i] + theta*dy[i]; w[i] = w[i] + theta*dw[i]; } phi = phi + theta*dphi; psi = psi + theta*dpsi; } for (j=0; j<n; j++) { x[j] /= phi; z[j] /= phi; } for (i=0; i<m; i++) { y[i] /= phi; w[i] /= phi; } /**************************************************************** * Free work space * ****************************************************************/ FREE( w ); FREE( z ); FREE( dx ); FREE( dw ); FREE( dy ); FREE( dz ); FREE( rho ); FREE( sigma ); FREE( D ); FREE( E ); FREE( fx ); FREE( fy ); FREE( gx ); FREE( gy ); FREE( At ); FREE( iAt ); FREE( kAt ); return status; } /* End of solver */