79 if(verbose>0) {printf(
"bvls(%d, %d, %d, ...)\n", key, m, n); fflush(stdout);}
81 if(a==NULL || b==NULL || bl==NULL || bu==NULL || x==NULL || w==NULL ||
82 act==NULL || zz==NULL || istate==NULL || iter==NULL || n<1 || m<1)
84 if(verbose>0) fprintf(stderr,
"Error: invalid input to BVLS.\n");
88 int maxIter=*iter;
if(maxIter<3) maxIter=3*n;
90 const double eps=1.0E-13;
93 if(verbose>1) {printf(
"step 1\n"); fflush(stdout);}
96 int mm;
if(m<n) mm=m;
else mm=n;
101 int istateFromStep5 = 0;
106 for(
int ni=0; ni<n; ni++) {
107 double d=bu[ni]-bl[ni];
108 if(verbose>3) printf(
" bounds[%d]: %g %g\n", 1+ni, bl[ni], bu[ni]);
110 if(verbose>0) fprintf(stderr,
"Error: inconsistent bounds in BVLS.\n");
113 maxrange=fmax(maxrange, d);
115 if(verbose>2) printf(
" maxrange := %g\n", maxrange);
116 if(maxrange<1.0E-10) {
117 if(verbose>0) fprintf(stderr,
"Error: no free variables in BVLS.\n");
129 for(
int ni=0; ni<nbound; ni++) istate[ni]=-(1+ni);
135 if(verbose>0) fprintf(stderr,
"Error: too many active variables in BVLS starting solution.\n");
138 for(
int ni=0; ni<nbound; ni++) {
139 int i=abs(istate[ni])-1;
140 if(istate[ni]<0) x[i]=bl[i];
else x[i]=bu[i];
146 for(
int ni=nbound; ni<n; ni++) {
147 int i=abs(istate[ni])-1;
148 x[i]=0.5*(bl[i]+bu[i]);
153 for(
int mi=0; mi<m; mi++) bnorm+=b[mi]*b[mi];
154 bnorm=sqrt(bnorm);
if(verbose>2) printf(
" initial_bnorm := %g\n", bnorm);
164 for(*iter=1; *iter<=maxIter; ++(*iter)) {
166 if(verbose>1) {printf(
"iteration %d\n", *iter); fflush(stdout);}
169 if(verbose>1) {printf(
" step 2\n"); fflush(stdout);}
172 for(
int ni=0; ni<n; ni++) w[ni]=0.0;
178 for(
int mi=0; mi<m; mi++) {
180 for(
int ni=0; ni<n; ni++) ri-=a[mi+ni*m]*x[ni];
182 for(
int ni=0; ni<n; ni++) w[ni]+=a[mi+ni*m]*ri;
185 if(verbose>3) {printf(
" obj := %g\n", obj); fflush(stdout);}
189 if((sqrt(obj)<=bnorm*eps) || ((*iter)>1 && nbound==0)) {
190 if(verbose>1) {printf(
"bvls converged.\n"); fflush(stdout);}
197 for(
int ni=nbound; ni<n; ni++) {
198 int i=abs(istate[ni])-1;
199 for(
int mi=0; mi<m; mi++) act[mi+mm*m] += a[mi+i*m]*x[i];
202 printf(
"Residual vector:\n");
203 for(
int mi=0; mi<m; mi++) printf(
"\t%g", act[mi+mm*m]);
213 if(key!=0 && (*iter)==1) {
214 if(verbose>1) printf(
" 'warm start' requires immediate QR in Step 6\n");
220 if(verbose>1) {printf(
" steps 3 and 4\n"); fflush(stdout);}
224 for(
int ni=0; ni<nbound; ni++) {
225 int i=abs(istate[ni])-1;
226 double bad;
if(istate[ni] < 0) bad=-w[i];
else bad=+w[i];
227 if(bad < worst) { it=ni+1; worst=bad; iact=i; }
232 if(verbose>1) {printf(
"Kuhn-Tucker condition is met.\n"); fflush(stdout);}
242 if(iact==(aindx-1)) w[aindx-1]=0.0;
243 }
while(iact==(aindx-1));
245 if(verbose>1) {printf(
" step 5\n"); fflush(stdout);}
248 if(istate[it-1]==0) {
249 if(verbose>0) fprintf(stderr,
"Error: BVLS istate is zero!\n");
254 if(istate[it-1]>0) bnd=bu[iact];
else bnd=bl[iact];
255 for(
int mi=0; mi<m; mi++) act[mi+mm*m]+=bnd*a[mi+iact*m];
262 istateFromStep5=istate[it-1];
266 istate[it-1]=istate[nbound-1];
268 istate[nbound]=1+iact;
270 if(verbose>0) fprintf(stderr,
"Error: too many free variables in BVLS.\n");
280 if(verbose>1) {printf(
" step 6\n"); fflush(stdout);}
285 for(
int mi=0; mi<m; mi++) {
286 act[mi+(mm+1)*m]=act[mi+mm*m];
287 for(
int ni=nbound; ni<n; ni++) {
288 int i=abs(istate[ni])-1;
289 act[mi+(nact+nbound-ni-1)*m]=a[mi+i*m];
293 printf(
"Matrix A for QR:\n");
294 for(
int ni=0; ni<nact; ni++) {
295 for(
int mi=0; mi<m; mi++) printf(
"\t%g", act[mi+ni*nact]);
298 printf(
"Vector B for QR:\n");
299 for(
int mi=0; mi<m; mi++) printf(
"\t%g", act[(mm+1)*m + mi]);
309 if(
qrLH(m, nact, act, &act[(mm+1)*m], zz, &r2) !=0 ||
310 (istateFromStep5>0 && zz[nact-1]>bu[iact]) ||
311 (istateFromStep5<0 && zz[nact-1]<bl[iact]) )
314 if(bu[iact]>x[iact]) istate[nbound-1]=-istate[nbound-1];
316 for(
int mi=0; mi<m; mi++) act[mi+mm*m]-=x[iact]*a[mi+iact*m];
320 if(verbose>3) {printf(
" going from step 6 to step 3\n"); fflush(stdout);}
327 if(istateFromStep5!=0) aindx=0;
330 if(verbose>1) {printf(
" step 7\n"); fflush(stdout);}
332 int qr_solution_feasible=1;
334 if(verbose>8) printf(
" nact=%d nbound=%d\n", nact, nbound);
335 for(
int ni=0; ni<nact; ni++) {
337 int i=abs(istate[ni+nbound])-1;
339 printf(
" istate[%d]=%d\n", ni+nbound, 1+i);
340 printf(
" zz[%d]=%g bl[%d]=%g bu[%d]=%g\n", nact-ni-1, zz[nact-ni-1], i, bl[i], i, bu[i]);
342 if(zz[nact-ni-1]<bl[i] || zz[nact-ni-1]>bu[i]) {
343 if(verbose>3) {printf(
" new iterate is not feasible\n"); fflush(stdout);}
344 qr_solution_feasible=0;
break;
347 if(verbose>8) printf(
" indexHolder=%d\n", indexHolder);
348 if(qr_solution_feasible) {
349 if(verbose>3) {printf(
" new iterate is feasible\n"); fflush(stdout);}
350 for(
int ni=0; ni<nact; ni++) {
351 int i=abs(istate[ni+nbound])-1;
360 if(verbose>1) {printf(
" steps 8 and 9\n"); fflush(stdout);}
362 for(
int ni=indexHolder; ni<nact; ni++) {
363 int i=abs(istate[ni+nbound])-1;
364 if(zz[nact-ni-1] > bu[i]) alf=(bu[i]-x[i])/(zz[nact-ni-1]-x[i]);
365 if(zz[nact-ni-1] < bl[i]) alf=(bl[i]-x[i])/(zz[nact-ni-1]-x[i]);
369 if((zz[nact-ni-1]-bl[i])<0.0) aindxsign=-1;
else aindxsign=+1;
372 if(verbose>1) {printf(
" step 10\n"); fflush(stdout);}
373 for(
int ni=0; ni<nact; ni++) {
374 int i=abs(istate[ni+nbound])-1;
375 x[i]+=alpha*(zz[nact-ni-1]-x[i]);
379 if(verbose>1) {printf(
" step 11\n"); fflush(stdout);}
389 for(
int ni=0; ni<nact; ni++) {
390 int i=abs(istate[ni+noldb])-1;
391 if((bu[i]-x[i]<=0.0) || (i==(aindx-1) && aindxsign>0)) {
394 istate[ni+noldb]=istate[nbound]; istate[nbound]=+(1+i); nbound++;
395 for(
int mi=0; mi<m; mi++) act[mi+mm*m]-=bu[i]*a[mi+i*m];
396 }
else if( ((x[i]-bl[i])<=0.0) || (i==(aindx-1) && aindxsign<0)) {
399 istate[ni+noldb]=istate[nbound]; istate[nbound]=-(1+i); nbound++;
400 for(
int mi=0; mi<m; mi++) act[mi+mm*m]-=bl[i]*a[mi+i*m];
411 if(verbose>0) fprintf(stderr,
"Error: BVLS fails to converge.\n");
int bvls(int key, const int m, const int n, double *a, double *b, double *bl, double *bu, double *x, double *w, double *act, double *zz, int *istate, int *iter, int verbose)
Bounded-value least-squares method to solve the linear problem A x ~ b , subject to limit1 <= x <= li...