67 int verbose=0;
if(status!=NULL) verbose=status->
verbose;
68 if(verbose>0) printf(
"%s()\n", __func__);
70 printf(
"%s(x, ", __func__);
71 if(x2==NULL) printf(
"null, y, ");
else printf(
"x2, y, ");
72 if(w==NULL) printf(
"null");
else printf(
"w");
73 printf(
" , %d, %.1e, %.1e, %d, %g, %g, %g, *k, *a, *dtEst, *yfit\n",
74 sNr, kMin, kMax, fNr, dtMin, dtMax, dtStep);
76 if(x==NULL || y==NULL) {
81 if(verbose>1) fprintf(stderr,
"invalid number of samples\n");
86 if(verbose>1) fprintf(stderr,
"invalid number of functions\n");
90 if(!(kMin>0.0) || !(kMax>kMin)) {
91 if(verbose>1) fprintf(stderr,
"invalid k range\n");
95 double dtRange=dtMax-dtMin;
96 if(!(dtRange>=0.0) || (dtRange>0.0 && !(dtStep<0.2*dtRange))) {
97 if(verbose>1) fprintf(stderr,
"invalid delay time settings\n");
103 double *lk, *la, *localp;
104 localp=(
double*)malloc(
sizeof(
double)*fNr*2);
109 lk=localp; la=localp+fNr;
111 if(verbose>2) printf(
"computing k values\n");
114 r1=log10(kMin); r2=log10(kMax); s=(r2-r1)/(
double)(fNr-1);
115 if(verbose>3) printf(
" r1 := %g\n r2 := %g\n s := %g\n", r1, r2, s);
116 for(
int bi=0; bi<fNr; bi++) lk[bi]=pow(10.0, (
double)bi*s+r1);
121 if(verbose>2) printf(
"allocating memory for LLSQ\n");
122 int nnls_n, nnls_m, nnls_index[fNr];
123 double *nnls_a[fNr], nnls_x[fNr], nnls_wp[fNr], *nnls_b, *nnls_zz, *nnls_mat, *dptr, nnls_r2;
124 nnls_n=fNr; nnls_m=sNr;
125 nnls_mat=(
double*)malloc(((nnls_n+2)*nnls_m)*
sizeof(
double));
132 for(
int n=0; n<nnls_n; n++) {nnls_a[n]=dptr; dptr+=nnls_m;}
133 nnls_b=dptr; dptr+=nnls_m; nnls_zz=dptr;
136 double initDeltaT=dtMin;
137 if(dtMax>dtMin) initDeltaT=0.5*(dtMin+dtMax);
138 if(verbose>3) printf(
"initDeltaT := %g\n", initDeltaT);
141 if(verbose>2) printf(
"LLSQ fitting\n");
142 double bestDeltaT=initDeltaT;
143 double bestR2=nan(
"");
144 double deltaT=initDeltaT;
145 if(verbose>2) printf(
" deltaT=%g\n", deltaT);
146 if(verbose>6) printf(
"filling data matrix\n");
148 for(
int m=0; m<nnls_m; m++) nnls_b[m]=y[m];
151 double p[3]={deltaT, 1.0, 0.0};
152 for(
int n=0; n<nnls_n && !ret; n++) {
155 ret=
mfEvalFrameY(
"dmsurge", 3, p, nnls_m, x, x2, nnls_a[n], 0);
157 ret=
mfEvalY(
"dmsurge", 3, p, nnls_m, x, nnls_a[n], 0);
160 free(nnls_mat); free(localp);
165 if(w!=NULL)
nnlsWght(nnls_n, nnls_m, nnls_a, nnls_b, w);
167 if(verbose>6) printf(
"applying NNLS\n");
168 ret=
nnls(nnls_a, nnls_m, nnls_n, nnls_b, nnls_x, &nnls_r2, nnls_wp, nnls_zz, nnls_index);
170 free(nnls_mat); free(localp);
174 if(verbose>2) printf(
" -> r2=%g\n", nnls_r2);
177 for(
int n=0; n<nnls_n; n++) la[n]=nnls_x[n];
180 deltaT=initDeltaT-dtStep;
181 while(dtStep>0.0 && deltaT>=dtMin) {
182 if(verbose>2) printf(
" deltaT=%g\n", deltaT);
183 for(
int m=0; m<nnls_m; m++) nnls_b[m]=y[m];
185 for(
int n=0; n<nnls_n && !ret; n++) {
188 ret=
mfEvalFrameY(
"dmsurge", 3, p, nnls_m, x, x2, nnls_a[n], 0);
190 ret=
mfEvalY(
"dmsurge", 3, p, nnls_m, x, nnls_a[n], 0);
193 free(nnls_mat); free(localp);
197 if(w!=NULL)
nnlsWght(nnls_n, nnls_m, nnls_a, nnls_b, w);
198 int ret=
nnls(nnls_a, nnls_m, nnls_n, nnls_b, nnls_x, &nnls_r2, nnls_wp, nnls_zz, nnls_index);
200 if(verbose>2) printf(
" -> r2=%g\n", nnls_r2);
204 for(
int n=0; n<nnls_n; n++) la[n]=nnls_x[n];
209 deltaT=initDeltaT+dtStep;
210 while(dtStep>0.0 && deltaT<=dtMax) {
211 if(verbose>2) printf(
" deltaT=%g\n", deltaT);
212 for(
int m=0; m<nnls_m; m++) nnls_b[m]=y[m];
216 for(
int n=0; n<nnls_n && !ret; n++) {
219 ret=
mfEvalFrameY(
"dmsurge", 3, p, nnls_m, x, x2, nnls_a[n], 0);
221 ret=
mfEvalY(
"dmsurge", 3, p, nnls_m, x, nnls_a[n], 0);
224 free(nnls_mat); free(localp);
229 if(w!=NULL)
nnlsWght(nnls_n, nnls_m, nnls_a, nnls_b, w);
230 int ret=
nnls(nnls_a, nnls_m, nnls_n, nnls_b, nnls_x, &nnls_r2, nnls_wp, nnls_zz, nnls_index);
233 if(verbose>2) printf(
" -> r2=%g\n", nnls_r2);
237 for(
int n=0; n<nnls_n; n++) la[n]=nnls_x[n];
247 if(verbose>1) printf(
"computing yfit[]\n");
248 for(
int m=0; m<nnls_m; m++) {
250 for(
int n=0; n<nnls_n; n++)
252 yfit[m]+=la[n]*(x[m]+bestDeltaT)*exp(-lk[n]*(x[m]+bestDeltaT));
257 if(a!=NULL)
for(
int bi=0; bi<fNr; bi++) a[bi]=la[bi];
258 if(k!=NULL)
for(
int bi=0; bi<fNr; bi++) k[bi]=lk[bi];
261 if(dtEst!=NULL) *dtEst=bestDeltaT;