TPCCLIB
Loading...
Searching...
No Matches
constraints.c
Go to the documentation of this file.
1
5/****************************************************************************/
6#include "libtpcmodel.h"
7/****************************************************************************/
8
9/****************************************************************************/
17 int par_nr,
19 double *lower_p,
21 double *upper_p,
23 double *test_p,
25 double *accept_p,
28 double *penalty
29) {
30 int pi, accept_nr=0;
31 double range;
32
33 if(penalty!=NULL) *penalty=1.0;
34 for(pi=0; pi<par_nr; pi++) {
35 range=upper_p[pi]-lower_p[pi]; if(range<=0.0) range=1.0;
36 if(test_p[pi]<lower_p[pi]) {
37 if(accept_p!=NULL) accept_p[pi]=lower_p[pi];
38 if(penalty!=NULL) *penalty += (lower_p[pi]-test_p[pi])/range;
39 } else if(test_p[pi]>upper_p[pi]) {
40 if(accept_p!=NULL) accept_p[pi]=upper_p[pi];
41 if(penalty!=NULL) *penalty += (test_p[pi]-upper_p[pi])/range;
42 } else {
43 if(accept_p!=NULL) accept_p[pi]=test_p[pi];
44 accept_nr++;
45 }
46 }
47 return accept_nr;
48}
49/****************************************************************************/
50
51/****************************************************************************/
61 int par_nr,
63 double *lower_p,
65 double *upper_p,
67 double *test_p
68) {
69 int pi, collision_nr=0;
70 double range, range_factor=0.00001;
71
72 for(pi=0; pi<par_nr; pi++) {
73 // fixed parameters are not checked
74 range=upper_p[pi]-lower_p[pi]; if(range<=0.0) continue;
75 // if parameter exceeds the limit, then that is a collision for sure
76 if(test_p[pi]<=lower_p[pi]) {
77 collision_nr++; continue;
78 } else if(test_p[pi]>upper_p[pi]) {
79 collision_nr++; continue;
80 }
81 // but in addition, accepted range is a bit smaller than constrained range
82 // except if limit is 0, then it is ok that parameter is close to zero
83 range*=range_factor;
84 if(test_p[pi]<lower_p[pi]+range) {
85 if(fabs(lower_p[pi])>=1.0E-06) collision_nr++;
86 } else if(test_p[pi]>upper_p[pi]-range) {
87 if(fabs(upper_p[pi])>=1.0E-06) collision_nr++;
88 }
89 }
90 return collision_nr;
91}
92/****************************************************************************/
93
94/****************************************************************************/
103 double *x,
105 double *y,
107 int n,
112 double fittime,
114 double kmin,
116 double kmax,
118 int pnr,
121 double *a,
124 double *k,
127 int *fnr,
129 int verbose
130) {
131 if(verbose>0)
132 printf("fitExpDecayNNLS(x, y, %d, %g, %g, %g, ...)\n", n, fittime, kmin, kmax);
133 if(n<3) return(1);
134 if(fittime>0.0) {
135 while(x[n-1]>fittime && n>0) n--;
136 if(verbose>1) printf(" n := %d\n", n);
137 }
138 if(kmin<1.0E-100) kmin=1.0E-100;
139 if(kmax<=kmin) return(1);
140
141 /* Allocate memory for NNLS */
142 int NNLS_N=100;
143 int nn, mm, nnls_n, nnls_m, nnls_index[NNLS_N];
144 double *nnls_a[NNLS_N], *nnls_b, *nnls_zz, nnls_x[NNLS_N], *nnls_mat,
145 nnls_wp[NNLS_N], *dptr, nnls_rnorm;
146
147 nnls_n=NNLS_N;
148 nnls_m=n;
149 nnls_mat=(double*)malloc(((nnls_n+2)*nnls_m)*sizeof(double));
150 if(nnls_mat==NULL) return(2);
151 for(nn=0, dptr=nnls_mat; nn<nnls_n; nn++) {nnls_a[nn]=dptr; dptr+=nnls_m;}
152 nnls_b=dptr; dptr+=nnls_m; nnls_zz=dptr;
153
154 /* Set exponent function decay parameters */
155 double epar[NNLS_N];
156 {
157 double elnmin, elnmax;
158 elnmin=log(kmin); elnmax=log(kmax);
159 //double elnmin=-12.5, elnmax=6.7;
160 double d, r;
161 r=elnmax-elnmin;
162 d=r/(double)(NNLS_N-1);
163 for(nn=0; nn<nnls_n; nn++) epar[nn]=-exp(elnmin+(double)nn*d);
164 }
165
166 /* Fill NNLS matrix */
167 for(mm=0; mm<nnls_m; mm++) {
168 nnls_b[mm]=y[mm];
169 }
170 for(nn=0; nn<nnls_n; nn++)
171 for(mm=0; mm<nnls_m; mm++)
172 nnls_a[nn][mm]=exp(epar[nn]*x[mm]);
173
174 /* NNLS */
175 int ret;
176 ret=nnls(nnls_a, nnls_m, nnls_n, nnls_b, nnls_x, &nnls_rnorm,
177 nnls_wp, nnls_zz, nnls_index);
178 if(ret>1) {
179 if(verbose>0) fprintf(stderr, "Error: NNLS solution not possible.\n");
180 free(nnls_mat);
181 return(3);
182 } else if(ret==1) {
183 if(verbose>0) fprintf(stderr, "Warning: max iteration count exceeded in NNLS.\n");
184 }
185 if(verbose>2) {
186 printf("NNLS results:\n");
187 for(nn=0; nn<nnls_n; nn++)
188 printf("\t%e\t%g\t%g\n", epar[nn], nnls_x[nn], nnls_wp[nn]);
189 }
190 if(verbose>1) {
191 printf("Reasonable NNLS results:\n");
192 for(nn=0; nn<nnls_n; nn++)
193 if(nnls_wp[nn]==0.0) printf("\t%e\t%g\n", epar[nn], nnls_x[nn]);
194 }
195
196 /* Reset exponent function decay parameters with the clusters found above */
197 {
198 if(verbose>1) printf("Cluster means:\n");
199 int i, j, nr;
200 double ev;
201 i=j=0;
202 while(1) {
203 /* jump over functions with wp<0 */
204 while(i<nnls_n && nnls_wp[i]<0.0) i++;
205 if(i==nnls_n) break;
206 /* calculate mean of this cluster */
207 nr=0; ev=0.0;
208 while(i<nnls_n && nnls_wp[i]==0.0) {nr++; ev+=epar[i]; i++;}
209 ev/=(double)nr;
210 if(verbose>1) printf("mean_e := %e\n", ev);
211 epar[j++]=ev;
212 }
213 nnls_n=j;
214 }
215
216 /* Fill NNLS matrix with these functions */
217 for(mm=0; mm<nnls_m; mm++) {
218 nnls_b[mm]=y[mm];
219 }
220 for(nn=0; nn<nnls_n; nn++)
221 for(mm=0; mm<nnls_m; mm++)
222 nnls_a[nn][mm]=exp(epar[nn]*x[mm]);
223
224 /* NNLS */
225 ret=nnls(nnls_a, nnls_m, nnls_n, nnls_b, nnls_x, &nnls_rnorm,
226 nnls_wp, nnls_zz, nnls_index);
227 if(ret>1) {
228 if(verbose>0) fprintf(stderr, "Error: NNLS solution not possible.\n");
229 free(nnls_mat);
230 return(3);
231 } else if(ret==1) {
232 if(verbose>0) fprintf(stderr, "Warning: max iteration count exceeded in NNLS.\n");
233 }
234 if(verbose>1) {
235 printf("NNLS results:\n");
236 for(nn=0; nn<nnls_n; nn++)
237 printf("\t%e\t%g\t%g\n", epar[nn], nnls_x[nn], nnls_wp[nn]);
238 }
239
240 /* Return the results */
241 int nr=0;
242 for(nn=0; nn<nnls_n; nn++) {
243 if(nnls_wp[nn]<0.0) continue;
244 if(nr>=pnr) {nr++; continue;}
245 if(a!=NULL) a[nr]=nnls_x[nn];
246 if(k!=NULL) k[nr]=epar[nn];
247 nr++;
248 }
249 if(fnr!=NULL) *fnr=nr;
250
251 free(nnls_mat);
252 return(0);
253}
254/*****************************************************************************/
255
256/*****************************************************************************/
int fitExpDecayNNLS(double *x, double *y, int n, double fittime, double kmin, double kmax, int pnr, double *a, double *k, int *fnr, int verbose)
Estimate initial values for sum of exponentials to be fitted on decaying x,y-data.
int modelCheckParameters(int par_nr, double *lower_p, double *upper_p, double *test_p, double *accept_p, double *penalty)
Definition constraints.c:15
int modelCheckLimits(int par_nr, double *lower_p, double *upper_p, double *test_p)
Definition constraints.c:59
Header file for libtpcmodel.
int nnls(double **a, int m, int n, double *b, double *x, double *rnorm, double *w, double *zz, int *index)
Definition nnls.c:38