73 if(verbose>0) {printf(
"bvls(%d, %d, %d, ...)\n", key, m, n); fflush(stdout);}
75 if(a==NULL || b==NULL || bl==NULL || bu==NULL || x==NULL || w==NULL ||
76 act==NULL || zz==NULL || istate==NULL || iter==NULL || n<1 || m<1)
78 if(verbose>0) fprintf(stderr,
"Error: invalid input to BVLS.\n");
82 int maxIter=*iter;
if(maxIter<3) maxIter=3*n;
84 const double eps=1.0E-13;
87 if(verbose>1) {printf(
"step 1\n"); fflush(stdout);}
90 int mm;
if(m<n) mm=m;
else mm=n;
95 int istateFromStep5 = 0;
100 for(
int ni=0; ni<n; ni++) {
101 double d=bu[ni]-bl[ni];
102 if(verbose>3) printf(
" bounds[%d]: %g %g\n", 1+ni, bl[ni], bu[ni]);
104 if(verbose>0) fprintf(stderr,
"Error: inconsistent bounds in BVLS.\n");
107 maxrange=fmax(maxrange, d);
109 if(verbose>2) printf(
" maxrange := %g\n", maxrange);
110 if(maxrange<1.0E-10) {
111 if(verbose>0) fprintf(stderr,
"Error: no free variables in BVLS.\n");
123 for(
int ni=0; ni<nbound; ni++) istate[ni]=-(1+ni);
129 if(verbose>0) fprintf(stderr,
"Error: too many active variables in BVLS starting solution.\n");
132 for(
int ni=0; ni<nbound; ni++) {
133 int i=abs(istate[ni])-1;
134 if(istate[ni]<0) x[i]=bl[i];
else x[i]=bu[i];
140 for(
int ni=nbound; ni<n; ni++) {
141 int i=abs(istate[ni])-1;
142 x[i]=0.5*(bl[i]+bu[i]);
147 for(
int mi=0; mi<m; mi++) bnorm+=b[mi]*b[mi];
148 bnorm=sqrt(bnorm);
if(verbose>2) printf(
" initial_bnorm := %g\n", bnorm);
158 for(*iter=1; *iter<=maxIter; ++(*iter)) {
160 if(verbose>1) {printf(
"iteration %d\n", *iter); fflush(stdout);}
163 if(verbose>1) {printf(
" step 2\n"); fflush(stdout);}
166 for(
int ni=0; ni<n; ni++) w[ni]=0.0;
172 for(
int mi=0; mi<m; mi++) {
174 for(
int ni=0; ni<n; ni++) ri-=a[mi+ni*m]*x[ni];
176 for(
int ni=0; ni<n; ni++) w[ni]+=a[mi+ni*m]*ri;
179 if(verbose>3) {printf(
" obj := %g\n", obj); fflush(stdout);}
183 if((sqrt(obj)<=bnorm*eps) || ((*iter)>1 && nbound==0)) {
184 if(verbose>1) {printf(
"bvls converged.\n"); fflush(stdout);}
191 for(
int ni=nbound; ni<n; ni++) {
192 int i=abs(istate[ni])-1;
193 for(
int mi=0; mi<m; mi++) act[mi+mm*m] += a[mi+i*m]*x[i];
196 printf(
"Residual vector:\n");
197 for(
int mi=0; mi<m; mi++) printf(
"\t%g", act[mi+mm*m]);
207 if(key!=0 && (*iter)==1) {
208 if(verbose>1) printf(
" 'warm start' requires immediate QR in Step 6\n");
214 if(verbose>1) {printf(
" steps 3 and 4\n"); fflush(stdout);}
218 for(
int ni=0; ni<nbound; ni++) {
219 int i=abs(istate[ni])-1;
220 double bad;
if(istate[ni] < 0) bad=-w[i];
else bad=+w[i];
221 if(bad < worst) { it=ni+1; worst=bad; iact=i; }
226 if(verbose>1) {printf(
"Kuhn-Tucker condition is met.\n"); fflush(stdout);}
236 if(iact==(aindx-1)) w[aindx-1]=0.0;
237 }
while(iact==(aindx-1));
239 if(verbose>1) {printf(
" step 5\n"); fflush(stdout);}
242 if(istate[it-1]==0) {
243 if(verbose>0) fprintf(stderr,
"Error: BVLS istate is zero!\n");
248 if(istate[it-1]>0) bnd=bu[iact];
else bnd=bl[iact];
249 for(
int mi=0; mi<m; mi++) act[mi+mm*m]+=bnd*a[mi+iact*m];
256 istateFromStep5=istate[it-1];
260 istate[it-1]=istate[nbound-1];
262 istate[nbound]=1+iact;
264 if(verbose>0) fprintf(stderr,
"Error: too many free variables in BVLS.\n");
274 if(verbose>1) {printf(
" step 6\n"); fflush(stdout);}
279 for(
int mi=0; mi<m; mi++) {
280 act[mi+(mm+1)*m]=act[mi+mm*m];
281 for(
int ni=nbound; ni<n; ni++) {
282 int i=abs(istate[ni])-1;
283 act[mi+(nact+nbound-ni-1)*m]=a[mi+i*m];
287 printf(
"Matrix A for QR:\n");
288 for(
int ni=0; ni<nact; ni++) {
289 for(
int mi=0; mi<m; mi++) printf(
"\t%g", act[mi+ni*nact]);
292 printf(
"Vector B for QR:\n");
293 for(
int mi=0; mi<m; mi++) printf(
"\t%g", act[(mm+1)*m + mi]);
303 if(
qrLH(m, nact, act, &act[(mm+1)*m], zz, &r2) !=0 ||
304 (istateFromStep5>0 && zz[nact-1]>bu[iact]) ||
305 (istateFromStep5<0 && zz[nact-1]<bl[iact]) )
308 if(bu[iact]>x[iact]) istate[nbound-1]=-istate[nbound-1];
310 for(
int mi=0; mi<m; mi++) act[mi+mm*m]-=x[iact]*a[mi+iact*m];
314 if(verbose>3) {printf(
" going from step 6 to step 3\n"); fflush(stdout);}
321 if(istateFromStep5!=0) aindx=0;
324 if(verbose>1) {printf(
" step 7\n"); fflush(stdout);}
326 int qr_solution_feasible=1;
328 if(verbose>8) printf(
" nact=%d nbound=%d\n", nact, nbound);
329 for(
int ni=0; ni<nact; ni++) {
331 int i=abs(istate[ni+nbound])-1;
333 printf(
" istate[%d]=%d\n", ni+nbound, 1+i);
334 printf(
" zz[%d]=%g bl[%d]=%g bu[%d]=%g\n", nact-ni-1, zz[nact-ni-1], i, bl[i], i, bu[i]);
336 if(zz[nact-ni-1]<bl[i] || zz[nact-ni-1]>bu[i]) {
337 if(verbose>3) {printf(
" new iterate is not feasible\n"); fflush(stdout);}
338 qr_solution_feasible=0;
break;
341 if(verbose>8) printf(
" indexHolder=%d\n", indexHolder);
342 if(qr_solution_feasible) {
343 if(verbose>3) {printf(
" new iterate is feasible\n"); fflush(stdout);}
344 for(
int ni=0; ni<nact; ni++) {
345 int i=abs(istate[ni+nbound])-1;
354 if(verbose>1) {printf(
" steps 8 and 9\n"); fflush(stdout);}
356 for(
int ni=indexHolder; ni<nact; ni++) {
357 int i=abs(istate[ni+nbound])-1;
358 if(zz[nact-ni-1] > bu[i]) alf=(bu[i]-x[i])/(zz[nact-ni-1]-x[i]);
359 if(zz[nact-ni-1] < bl[i]) alf=(bl[i]-x[i])/(zz[nact-ni-1]-x[i]);
363 if((zz[nact-ni-1]-bl[i])<0.0) aindxsign=-1;
else aindxsign=+1;
366 if(verbose>1) {printf(
" step 10\n"); fflush(stdout);}
367 for(
int ni=0; ni<nact; ni++) {
368 int i=abs(istate[ni+nbound])-1;
369 x[i]+=alpha*(zz[nact-ni-1]-x[i]);
373 if(verbose>1) {printf(
" step 11\n"); fflush(stdout);}
383 for(
int ni=0; ni<nact; ni++) {
384 int i=abs(istate[ni+noldb])-1;
385 if((bu[i]-x[i]<=0.0) || (i==(aindx-1) && aindxsign>0)) {
388 istate[ni+noldb]=istate[nbound]; istate[nbound]=+(1+i); nbound++;
389 for(
int mi=0; mi<m; mi++) act[mi+mm*m]-=bu[i]*a[mi+i*m];
390 }
else if( ((x[i]-bl[i])<=0.0) || (i==(aindx-1) && aindxsign<0)) {
393 istate[ni+noldb]=istate[nbound]; istate[nbound]=-(1+i); nbound++;
394 for(
int mi=0; mi<m; mi++) act[mi+mm*m]-=bl[i]*a[mi+i*m];
405 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...