13#include "tpcclibConfig.h"
32int nnlsq_lss_h12(
int mode,
int lpivot,
int l1,
int m,
double *u,
double *up,
double *cm);
33void nnlsq_lss_g1(
double a,
double b,
double *cterm,
double *sterm,
double *sig);
65 if(verbose>0) {printf(
"%s()\n", __func__); fflush(stdout);}
68 if(d==NULL || d->
m<1 || d->
n<1 || d->
a==NULL || d->
b==NULL ||
69 d->
x==NULL || d->
w==NULL || d->
zz==NULL || d->
index==NULL)
71 if(d->
depf<1.0E-08 || d->
depf>0.5)
return(3);
74 for(
int ni=0; ni<d->
n; ni++) d->
x[ni]=0.0;
75 for(
int ni=0; ni<d->
n; ni++) d->
index[ni]=ni;
89 while(iz1<=iz2 && nsetp<d->m) {
91 for(
int iz=iz1; iz<=iz2; iz++) {
94 for(
int mi=npp1; mi<d->
m; mi++) sm+=d->
a[ni][mi]*d->
b[mi];
104 for(
int iz=iz1; iz<=iz2; iz++) {
106 if(d->
w[i]>wmax) {wmax=d->
w[i]; izmax=iz;}
115 double asave=d->
a[j][npp1];
117 if(nnlsq_lss_h12(1, npp1, npp1+1, d->
m, d->
a[j], &up, NULL))
return(2);
119 if(nsetp!=0)
for(
int mi=0; mi<nsetp; mi++) unorm+=d->
a[j][mi]*d->
a[j][mi];
121 double e=unorm+fabs(d->
a[j][npp1])*d->
depf;
125 for(
int mi=0; mi<d->
m; mi++) d->
zz[mi]=d->
b[mi];
126 nnlsq_lss_h12(2, npp1, npp1+1, d->
m, d->
a[j], &up, d->
zz);
127 double ztest=d->
zz[npp1]/d->
a[j][npp1];
134 d->
a[j][npp1]=asave; d->
w[j]=0.;
141 for(
int mi=0; mi<d->
m; mi++) d->
b[mi]=d->
zz[mi];
142 d->
index[izmax]=d->
index[iz1]; d->
index[iz1]=j; iz1++; nsetp=npp1+1; npp1++;
144 for(
int jz=iz1; jz<=iz2; jz++) {
146 nnlsq_lss_h12(2, nsetp-1, npp1, d->
m, d->
a[j], &up, d->
a[jj]);
148 if(nsetp!=d->
m)
for(
int mi=npp1; mi<d->
m; mi++) d->
a[j][mi]=0.;
152 for(
int mi=0; mi<nsetp; mi++) {
154 if(mi!=0)
for(
int ii=0; ii<=ip; ii++) d->
zz[ii]-=d->
a[jj][ii]*d->
zz[ip+1];
155 jj=d->
index[ip]; d->
zz[ip]/=d->
a[jj][ip];
159 while(++iter<itermax) {
162 for(
int ip=0; ip<nsetp; ip++) {
165 double t=-d->
x[ni]/(d->
zz[ip]-d->
x[ni]);
166 if(alpha>t) {alpha=t; jj=ip-1;}
172 if(alpha==2.0)
break;
175 for(
int ip=0; ip<nsetp; ip++) {
176 int ni=d->
index[ip]; d->
x[ni]+=alpha*(d->
zz[ip]-d->
x[ni]);
181 int k=d->
index[jj+1];
186 for(
int ni=jj+1; ni<nsetp; ni++) {
189 nnlsq_lss_g1(d->
a[ii][ni-1], d->
a[ii][ni], &cc, &ss, &d->
a[ii][ni-1]);
191 for(
int nj=0; nj<d->
n; nj++)
if(nj!=ii) {
193 double temp=d->
a[nj][ni-1];
194 d->
a[nj][ni-1]=cc*temp+ss*d->
a[nj][ni];
195 d->
a[nj][ni]=-ss*temp+cc*d->
a[nj][ni];
198 double temp=d->
b[ni-1];
199 d->
b[ni-1]=cc*temp+ss*d->
b[ni];
200 d->
b[ni]=-ss*temp+cc*d->
b[ni];
203 npp1=nsetp-1; nsetp--; iz1--; d->
index[iz1]=k;
209 for(jj=0; jj<nsetp; jj++) {
210 k=d->
index[jj];
if(d->
x[k]<=0.) {pfeas=0;
break;}
215 for(
int mi=0; mi<d->
m; mi++) d->
zz[mi]=d->
b[mi];
216 for(
int mi=0; mi<nsetp; mi++) {
218 if(mi!=0)
for(
int ii=0; ii<=ip; ii++) d->
zz[ii]-=d->
a[jj][ii]*d->
zz[ip+1];
219 jj=d->
index[ip]; d->
zz[ip]/=d->
a[jj][ip];
223 if(iter>=itermax)
break;
224 for(
int ip=0; ip<nsetp; ip++) {
int k=d->
index[ip]; d->
x[k]=d->
zz[ip];}
227 if(npp1>=d->
m)
for(
int ni=0; ni<d->
n; ni++) d->
w[ni]=0.;
231 for(
int mi=npp1; mi<d->
m; mi++) d->
rnorm+=(d->
b[mi]*d->
b[mi]);
234 if(verbose>2) printf(
" %d iterations.\n", iter);
236 if(verbose>1) printf(
" max iterations reached.\n");
274 if(mode!=1 && mode!=2)
return(1);
275 if(u==NULL || up==NULL)
return(2);
276 if(lpivot<0 || l1<0 || m<0)
return(3);
277 if(lpivot>=m || lpivot>=l1 || l1>m)
return(4);
279 double cl = fabs(u[lpivot]);
280 if(mode==2 && cl<=0.)
return(0);
284 for(
int j=l1; j<m; j++) {
285 cl = fmax(fabs(u[j]), cl);
288 if(cl<=0.)
return(0);
292 double d1=u[lpivot]*clinv;
294 for(
int j=l1; j<m; j++) {
295 double d2=u[j]*clinv;
299 if(u[lpivot] > 0.) cl=-cl;
300 *up = u[lpivot] - cl;
305 double b=(*up)*u[lpivot];
308 if(b>=0.0)
return(0);
312 double sm = cm[lpivot] * (*up);
313 for(
int k=l1; k<m; k++) sm += cm[k] * u[k];
316 cm[lpivot] += sm*(*up);
317 for(
int k=l1; k<m; k++) cm[k] += u[k]*sm;
333void nnlsq_lss_g1(
double a,
double b,
double *cterm,
double *sterm,
double *sig)
337 if(fabs(a)>fabs(b)) {
338 xr=b/a; d1=xr; yr=hypot(d1, 1.0); d1=1./yr;
339 *cterm=copysign(d1, a);
340 *sterm=(*cterm)*xr; *sig=fabs(a)*yr;
342 xr=a/b; d1=xr; yr=hypot(d1, 1.0); d1=1./yr;
343 *sterm=copysign(d1, b);
344 *cterm=(*sterm)*xr; *sig=fabs(b)*yr;
346 *sig=0.; *cterm=0.; *sterm=1.;
386#ifdef TEST_BUFOVERFLOW
387 fprintf(stderr,
"testing if buffer overflow happened\n"); fflush(stderr);
388 if(d->
index[d->
n]!=999) fprintf(stderr,
"BUFFER OVERFLOW 1\n");
389 if(!isnan(d->
_data[d->
m*d->
n])) fprintf(stderr,
"BUFFER OVERFLOW 2\n");
390 if(!isnan(d->
b[d->
m])) fprintf(stderr,
"BUFFER OVERFLOW 3\n");
391 if(!isnan(d->
x[d->
n])) fprintf(stderr,
"BUFFER OVERFLOW 4\n");
392 if(!isnan(d->
w[d->
n])) fprintf(stderr,
"BUFFER OVERFLOW 5\n");
393 if(!isnan(d->
zz[d->
m])) fprintf(stderr,
"BUFFER OVERFLOW 6\n");
394 fprintf(stderr,
"tested buffer overflow\n"); fflush(stderr);
426 int s = n*m + m + n + n + m;
427#ifdef TEST_BUFOVERFLOW
430 d->
_data=(
double*)malloc(
sizeof(
double)*s);
432 for(
int i=0; i<s; i++) d->
_data[i]=nan(
"");
434 d->
a=(
double**)malloc(
sizeof(
double*)*n);
437 for(
int i=0; i<n; i++) d->
a[i] = d->
_data + i*m;
439 d->
x = d->
_data + n*m + m;
440 d->
w = d->
_data + n*m + m + n;
441 d->
zz = d->
_data + n*m + m + n + n;
442#ifdef TEST_BUFOVERFLOW
443 d->
b++; d->
x+=2; d->
w+=3; d->
zz+=4;
447#ifdef TEST_BUFOVERFLOW
448 d->
index=(
int*)malloc(
sizeof(
int)*(1+n));
451 d->
index=(
int*)malloc(
sizeof(
int)*n);
476 if(d==NULL || d->
n<1 || d->
m<1 || d->
a==NULL || d->
b==NULL || weight==NULL)
return(1);
480 for(
int mi=0; mi<d->
m; mi++) {
481 if(weight[mi]<=1.0e-20) w[mi]=0.0;
482 else w[mi]=sqrt(weight[mi]);
486 for(
int mi=0; mi<d->
m; mi++) {
487 for(
int ni=0; ni<d->
n; ni++) {
512 if(d==NULL || d->
n<1 || d->
m<1 || d->
a==NULL || d->
b==NULL || sweight==NULL)
return(1);
515 for(
int mi=0; mi<d->
m; mi++) {
516 for(
int ni=0; ni<d->
n; ni++) {
517 d->
a[ni][mi]*=sweight[mi];
519 d->
b[mi]*=sweight[mi];
void nnlsqDataFree(NNLSQDATA *d)
int nnlsqDataAllocate(NNLSQDATA *d, const int n, const int m)
void nnlsqDataInit(NNLSQDATA *d)
int nnlsqWghtSquared(NNLSQDATA *d, double *sweight)
int nnlsqWght(NNLSQDATA *d, double *weight)
int nnlsq(NNLSQDATA *d, int verbose)
Header file for library libtpcextensions.
@ TPCERROR_FAIL
General error.
@ TPCERROR_OUT_OF_MEMORY
Cannot allocate memory.
Header file for libtpclinopt.