TPCCLIB
Loading...
Searching...
No Matches
par.c
Go to the documentation of this file.
1
4/*****************************************************************************/
5#include "tpcclibConfig.h"
6/*****************************************************************************/
7#include <stdio.h>
8#include <stdlib.h>
9#include <math.h>
10#include <time.h>
11#include <string.h>
12/*****************************************************************************/
13#include "tpcextensions.h"
14#include "tpcmodels.h"
15#include "tpcift.h"
16/*****************************************************************************/
17#include "tpcpar.h"
18/*****************************************************************************/
19
20/*****************************************************************************/
27 PAR *par
28) {
29 if(par==NULL) return;
31 par->tacNr=par->_tacNr=0;
32 par->parNr=par->_parNr=0;
33 par->n=NULL;
34 par->r=NULL;
35 iftInit(&par->h);
36}
43 PARR *parr
44) {
45 if(parr==NULL) return;
46 parr->model=0;
47 parr->name[0]='\0';
48 parr->start=parr->end=nan("");
49 parr->fitNr=0;
50 parr->dataNr=0;
51 parr->p=parr->sd=parr->cl1=parr->cl2=NULL;
52 parr->wss=nan("");
53 parr->sw=0;
54}
61 PARN *parn
62) {
63 if(parn==NULL) return;
64 parn->name[0]='\0';
65 parn->unit=UNIT_UNKNOWN;
66 parn->lim1=parn->lim2=parn->tol=nan("");
67 parn->sw=0;
68}
69/*****************************************************************************/
70
71/*****************************************************************************/
77 PAR *par
78) {
79 if(par==NULL) return;
80 for(int i=0; i<par->_tacNr; i++) parrFree(par->r+i);
81 free(par->r);
82 free(par->n);
83 iftFree(&par->h);
84 parInit(par);
85}
89 PARR *parr
90) {
91 if(parr==NULL) return;
92 free(parr->p);
93 free(parr->sd);
94 free(parr->cl1);
95 free(parr->cl2);
96 parrInit(parr);
97}
98/*****************************************************************************/
99
100/*****************************************************************************/
111 PAR *par,
113 int parNr,
115 int tacNr
116) {
117 if(par==NULL) return TPCERROR_FAIL;
118 /* Delete any previous contents */
119 parFree(par);
120 /* If no memory is requested, then just return */
121 if(parNr<1 && tacNr<1) return TPCERROR_OK;
122 if(parNr<1 || tacNr<1) return TPCERROR_FAIL;
123
124 /* Allocate memory for PARR data */
125 int ret;
126 par->r=(PARR*)malloc(tacNr*sizeof(PARR));
127 if(par->r==NULL) return TPCERROR_OUT_OF_MEMORY;
128 for(int i=0; i<tacNr; i++) {
129 parrInit(&par->r[i]);
130 ret=parrAllocate(par->r+i, parNr); if(ret!=TPCERROR_OK) return ret;
131 }
132 par->_tacNr=tacNr;
133
134 /* Allocate memory for parameter names and units */
135 par->n=(PARN*)malloc(parNr*sizeof(PARN));
136 if(par->n==NULL) return TPCERROR_OUT_OF_MEMORY;
137 for(int i=0; i<parNr; i++) parnInit(&par->n[i]);
138 par->_parNr=parNr;
139
140 return TPCERROR_OK;
141}
142/*****************************************************************************/
143
144/*****************************************************************************/
152 PARR *parr,
154 int parNr
155) {
156 if(parr==NULL) return TPCERROR_FAIL;
157 /* Delete any previous contents */
158 parrFree(parr);
159 /* If no memory is requested, then just return */
160 if(parNr<1) return TPCERROR_OK;
161
162 /* Allocate memory for PARR data */
163 parr->p=malloc(parNr*sizeof(double));
164 parr->sd=malloc(parNr*sizeof(double));
165 parr->cl1=malloc(parNr*sizeof(double));
166 parr->cl2=malloc(parNr*sizeof(double));
167 if(parr->p==NULL || parr->sd==NULL || parr->cl1==NULL || parr->cl2==NULL)
169 /* Initiate values to NaNs */
170 for(int i=0; i<parNr; i++)
171 parr->p[i]=parr->sd[i]=parr->cl1[i]=parr->cl2[i]=nan("");
172
173 return TPCERROR_OK;
174}
175/*****************************************************************************/
176
177/*****************************************************************************/
186 PAR *par,
189 int parNr,
192 int tacNr
193) {
194 if(par==NULL) return TPCERROR_FAIL;
195 if(par->_parNr<1 || par->_tacNr<1) return TPCERROR_FAIL;
196 if(parNr<0 || tacNr<0) return TPCERROR_FAIL;
197 /* Check if there is enough space already */
198 int newTacNr, addTacNr, newParNr, addParNr;
199 newTacNr=par->tacNr+tacNr; addTacNr=newTacNr-par->_tacNr;
200 newParNr=par->parNr+parNr; addParNr=newParNr-par->_parNr;
201 if(addTacNr<=0 && addParNr<=0) return TPCERROR_OK;
202
203 /* Reallocate memory for parameter names and units, if necessary */
204 if(addParNr>0) {
205 PARN *parnPtr;
206 parnPtr=realloc(par->n, sizeof(PARN)*newParNr);
207 if(parnPtr==NULL) return TPCERROR_OUT_OF_MEMORY;
208 par->n=parnPtr;
209 parnPtr+=par->_parNr; for(int i=0; i<addParNr; i++) parnInit(parnPtr++);
210 }
211
212 /* Reallocate memory for parameters of previous TACs, if necessary */
213 if(addParNr>0) {
214 int i, j;
215 for(i=0; i<par->tacNr; i++) {
216 par->r[i].p=realloc(par->r[i].p, sizeof(double)*newParNr);
217 par->r[i].sd=realloc(par->r[i].sd, sizeof(double)*newParNr);
218 par->r[i].cl1=realloc(par->r[i].cl1, sizeof(double)*newParNr);
219 par->r[i].cl2=realloc(par->r[i].cl2, sizeof(double)*newParNr);
220 if(par->r[i].p==NULL || par->r[i].sd==NULL || par->r[i].cl1==NULL || par->r[i].cl2==NULL)
222 for(j=par->parNr; j<newParNr; j++)
223 par->r[i].p[j]=par->r[i].sd[j]=par->r[i].cl1[j]=par->r[i].cl2[j]=nan("");
224 }
225 }
226
227 /* Allocate memory for more TACs, if necessary */
228 if(addTacNr>0) {
229 PARR *parrPtr;
230 parrPtr=realloc(par->r, sizeof(PARR)*newTacNr);
231 if(parrPtr==NULL) return TPCERROR_OUT_OF_MEMORY;
232 par->r=parrPtr;
233 parrPtr+=par->_tacNr;
234 for(int i=0; i<addTacNr; i++, parrPtr++) {
235 parrInit(parrPtr);
236 if(parrAllocate(parrPtr, newParNr)!=TPCERROR_OK)
238 }
239 }
240
241 par->_parNr=newParNr;
242 par->_tacNr=newTacNr;
243 return TPCERROR_OK;
244}
245/*****************************************************************************/
246
247/*****************************************************************************/
254 PAR *par
255) {
256 if(par==NULL || par->tacNr<1) return(0);
257 for(int ri=0; ri<par->tacNr; ri++) if(!isnan(par->r[ri].wss)) return(1);
258 return(0);
259}
260/*****************************************************************************/
261
262/*****************************************************************************/
269 PAR *par
270) {
271 if(par==NULL || par->tacNr<1) return(0);
272 int ri, ret=0;
273 for(ri=0; ri<par->tacNr; ri++) {
274 if(!isnan(par->r[ri].start) || !isnan(par->r[ri].end)) ret=1;
275 if(ri==0 || ret==0) continue;
276 if(!doubleMatch(par->r[ri].start, par->r[0].start, 0.01)) {ret=2; break;}
277 if(!doubleMatch(par->r[ri].end, par->r[0].end, 0.01)) {ret=2; break;}
278 }
279 return(ret);
280}
281/*****************************************************************************/
282
283/*****************************************************************************/
290 PAR *par
291) {
292 if(par==NULL || par->tacNr<1) return(0);
293 int ri, ret=0;
294 for(ri=0; ri<par->tacNr; ri++) {
295 if(ret==0 && par->r[ri].model>0) ret=1;
296 if(ri>0 && par->r[ri].model!=par->r[ri-1].model) {ret=2; break;}
297 }
298 return(ret);
299}
300/*****************************************************************************/
301
302/*****************************************************************************/
309 PAR *par,
311 int pi
312) {
313 //printf("%s(%d)\n", __func__, pi); fflush(stdout);
314 if(par==NULL || par->tacNr<1 || pi<0 || pi>=par->parNr) return(0);
315 for(int i=0; i<par->tacNr; i++) if(!isnan(par->r[i].sd[pi])) return(1);
316 return(0);
317}
318/*****************************************************************************/
319
320/*****************************************************************************/
327 PAR *par,
329 int pi
330) {
331 if(par==NULL || par->tacNr<1 || pi<0 || pi>=par->parNr) return(0);
332 for(int i=0; i<par->tacNr; i++)
333 if(!isnan(par->r[i].cl1[pi]) && !isnan(par->r[i].cl2[pi])) return(1);
334 return(0);
335}
336/*****************************************************************************/
337
338/*****************************************************************************/
345 PAR *par
346) {
347 if(par==NULL || par->tacNr<1) return(0);
348 int ri, ret=0;
349 for(ri=0; ri<par->tacNr; ri++) {
350 if(ret==0 && par->r[ri].fitNr>0) ret=1;
351 if(ri>0 && par->r[ri].fitNr!=par->r[ri-1].fitNr) {ret=2; break;}
352 }
353 return(ret);
354}
355/*****************************************************************************/
356
357/*****************************************************************************/
364 PAR *par
365) {
366 if(par==NULL || par->tacNr<1) return(0);
367 int ri, ret=0;
368 for(ri=0; ri<par->tacNr; ri++) {
369 if(ret==0 && par->r[ri].dataNr>0) ret=1;
370 if(ri>0 && par->r[ri].dataNr!=par->r[ri-1].dataNr) {ret=2; break;}
371 }
372 return(ret);
373}
374/*****************************************************************************/
375
376/*****************************************************************************/
383 PAR *par
384) {
385 if(par==NULL || par->h.keyNr<1) return((char*)NULL);
386 int li=iftFindKey(&par->h, "optimality_criterion", 0);
387 if(li<0) li=iftFindKey(&par->h, "optcrit", 0);
388 if(li<0) return((char*)NULL);
389 if(par->h.item[li].value==NULL || strlen(par->h.item[li].value)<1) return((char*)NULL);
390 return(par->h.item[li].value);
391}
392/*****************************************************************************/
393
394/*****************************************************************************/
401 PAR *par
402) {
403 if(par==NULL || par->h.keyNr<1) return((char*)NULL);
404 int li=iftFindKey(&par->h, "studynr", 0);
405 if(li<0) li=iftFindKey(&par->h, "study_number", 0);
406 if(li<0) return((char*)NULL);
407 if(par->h.item[li].value==NULL || strlen(par->h.item[li].value)<1) return((char*)NULL);
408 return(par->h.item[li].value);
409}
410/*****************************************************************************/
411
412/*****************************************************************************/
419 PAR *par,
422 const char *s
423) {
424 if(par==NULL) return TPCERROR_FAIL;
425
426 /* Find and delete previous studynr(s) */
427 int i=0, start=0;
428 while(1) {
429 i=iftFindKey(&par->h, "studynr", start);
430 if(i<0) i=iftFindKey(&par->h, "study_number", start);
431 if(i<0) i=iftFindKey(&par->h, "study number", start);
432 if(i<0) break;
433 iftDelete(&par->h, i); if(i>start) start=i;
434 }
435
436 /* If new studynr is empty, then just return */
437 if(s==NULL || *s=='\0') return(TPCERROR_OK);
438
439 /* Otherwise create new key and value */
440 return(iftPut(&par->h, "studynr", s, (char)1, NULL));
441}
442/*****************************************************************************/
443
444/*****************************************************************************/
451 PAR *d
452) {
453 if(d==NULL || d->tacNr<1 || d->parNr<1) return;
454 /* Ensure TAC names */
455 int u, n;
456 u=d->tacNr; n=1; while((u/=10)>=1) n++;
458 for(int i=0; i<d->tacNr; i++) {
459 if(strlen(d->r[i].name)<1 || strcmp(d->r[i].name, ".")==0)
460 sprintf(d->r[i].name, "%0*d", n, 1+i);
461 }
462 /* Ensure parameter names */
463 u=d->parNr; n=1; while((u/=10)>=1) n++;
465 for(int i=0; i<d->parNr; i++) {
466 if(strlen(d->n[i].name)<1 || strcmp(d->n[i].name, ".")==0)
467 sprintf(d->n[i].name, "P%0*d", n, 1+i);
468 }
469 return;
470}
471/*****************************************************************************/
472
473/*****************************************************************************/
480 PAR *par,
482 int pi
483) {
484 if(par==NULL || par->tacNr<1 || pi<0 || pi>=par->parNr) return(TPCERROR_FAIL);
485 if(pi==par->parNr-1) {par->parNr--; return(TPCERROR_OK);}
486
487 int i, j;
488
489 /* Parameter name and unit */
490 PARN parn;
491 memcpy(&parn, &par->n[pi], sizeof(PARN));
492 for(i=pi+1; i<par->parNr; i++)
493 memcpy(&par->n[i-1], &par->n[i], sizeof(PARN));
494 memcpy(&par->n[par->parNr-1], &parn, sizeof(PARN));
495
496 /* Parameter values */
497 double p, sd, cl1, cl2;
498 for(j=0; j<par->tacNr; j++) {
499 p=par->r[j].p[pi]; sd=par->r[j].sd[pi];
500 cl1=par->r[j].cl1[pi]; cl2=par->r[j].cl2[pi];
501 for(i=pi+1; i<par->parNr; i++) {
502 par->r[j].p[i-1]=par->r[j].p[i]; par->r[j].sd[i-1]=par->r[j].sd[i];
503 par->r[j].cl1[i-1]=par->r[j].cl1[i]; par->r[j].cl2[i-1]=par->r[j].cl2[i];
504 }
505 par->r[j].p[par->parNr-1]=p; par->r[j].sd[par->parNr-1]=sd;
506 par->r[j].cl1[par->parNr-1]=cl1; par->r[j].cl2[par->parNr-1]=cl2;
507 }
508
509 par->parNr--;
510 return(TPCERROR_OK);
511}
512/*****************************************************************************/
513
514/*****************************************************************************/
521 PAR *par,
523 int ti
524) {
525 if(par==NULL || par->tacNr<1 || ti<0 || ti>=par->tacNr) return(TPCERROR_FAIL);
526 /* Free the memory allocated for the TAC */
527 parrFree(par->r+ti);
528 /* If the last TAC is to be deleted, then just reduce the tacNr */
529 if(ti==par->tacNr-1) {par->tacNr--; return(TPCERROR_OK);}
530 /* Otherwise move the following TACs in its place */
531 for(int i=ti+1; i<par->tacNr; i++) par->r[i-1]=par->r[i];
532 par->tacNr--; parrInit(par->r+par->tacNr);
533 return(TPCERROR_OK);
534}
535/*****************************************************************************/
536
537/*****************************************************************************/
int doubleMatch(const double v1, const double v2, const double lim)
Definition doubleutil.c:27
void iftFree(IFT *ift)
Definition ift.c:37
int iftPut(IFT *ift, const char *key, const char *value, char comment, TPCSTATUS *status)
Definition ift.c:63
void iftInit(IFT *ift)
Definition ift.c:21
int iftDelete(IFT *ift, int index)
Definition ift.c:206
int iftFindKey(IFT *ift, const char *key, int start_index)
Definition iftfind.c:30
int parIsFitRange(PAR *par)
Definition par.c:267
int parSDWithPar(PAR *par, int pi)
Definition par.c:307
char * parIsOptcrit(PAR *par)
Definition par.c:381
void parrFree(PARR *parr)
Definition par.c:87
int parDeletePar(PAR *par, int pi)
Definition par.c:478
void parFree(PAR *par)
Definition par.c:75
int parAllocate(PAR *par, int parNr, int tacNr)
Definition par.c:108
int parCLWithPar(PAR *par, int pi)
Definition par.c:325
void parEnsureNames(PAR *d)
Definition par.c:449
int parIsFitNr(PAR *par)
Definition par.c:343
int parrAllocate(PARR *parr, int parNr)
Definition par.c:150
int parIsWSS(PAR *par)
Definition par.c:252
int parIsDataNr(PAR *par)
Definition par.c:362
int parIsModel(PAR *par)
Definition par.c:288
void parrInit(PARR *parr)
Definition par.c:41
char * parIsStudyNr(PAR *par)
Definition par.c:399
void parnInit(PARN *parn)
Definition par.c:59
void parInit(PAR *par)
Definition par.c:25
int parDeleteTAC(PAR *par, int ti)
Definition par.c:519
int parSetStudyNr(PAR *par, const char *s)
Definition par.c:417
int parAllocateMore(PAR *par, int parNr, int tacNr)
Definition par.c:183
char * value
Definition tpcift.h:37
IFT_ITEM * item
Definition tpcift.h:57
int keyNr
Definition tpcift.h:47
Definition tpcpar.h:101
int format
Definition tpcpar.h:103
IFT h
Optional (but often useful) header information.
Definition tpcpar.h:148
int _parNr
Definition tpcpar.h:111
int parNr
Definition tpcpar.h:109
int tacNr
Definition tpcpar.h:105
PARR * r
Definition tpcpar.h:115
int _tacNr
Definition tpcpar.h:107
PARN * n
Definition tpcpar.h:113
Definition tpcpar.h:81
int unit
Definition tpcpar.h:87
double lim2
Definition tpcpar.h:91
char sw
Definition tpcpar.h:95
double tol
Definition tpcpar.h:93
char name[MAX_PARNAME_LEN+1]
Definition tpcpar.h:83
double lim1
Definition tpcpar.h:89
Definition tpcpar.h:46
double wss
Definition tpcpar.h:73
int fitNr
Definition tpcpar.h:59
char name[MAX_TACNAME_LEN+1]
Definition tpcpar.h:50
int dataNr
Definition tpcpar.h:63
double * cl2
Definition tpcpar.h:71
char sw
Definition tpcpar.h:75
unsigned int model
Definition tpcpar.h:48
double * p
Definition tpcpar.h:65
double start
Definition tpcpar.h:52
double * sd
Definition tpcpar.h:67
double * cl1
Definition tpcpar.h:69
double end
Definition tpcpar.h:54
Header file for library libtpcextensions.
#define MAX_TACNAME_LEN
Max length of TAC ID name (not including trailing zero)
@ UNIT_UNKNOWN
Unknown unit.
#define MAX_PARNAME_LEN
Max string length for PAR name.
@ TPCERROR_FAIL
General error.
@ TPCERROR_OUT_OF_MEMORY
Cannot allocate memory.
@ TPCERROR_OK
No error.
Header file for library libtpcift.
Header file for libtpcmodels.
Header file for libtpcpar.
@ PAR_FORMAT_UNKNOWN
Unknown format.
Definition tpcpar.h:28