#include #include #include #include #ifdef UNIX #include #include #endif #include "guisdap.h" #include "GULIPS.h" #ifdef GUPTHREAD #include #include #endif struct pth { long ns; long aaN; double *aaPr; double *coefPr; long womM; double *womPr; double *kd2Pr; long nom; double *omPr; double *pldfvPr; double *pldfvPi; double *acfPr; unsigned long nag; unsigned long *ag; unsigned long nas; unsigned long *as; double *dyda; unsigned long nvarOK; unsigned long *varOK; double *ya; unsigned long i; pthread_mutex_t val_lock; double *aaOutPr; unsigned long yaSize; unsigned long *afree; unsigned long nscr; unsigned long nscr1; double *scr; double *scr1; unsigned long nth; double *p_m0; unsigned long nion; double *bwomPr; }; void *dirthe_loop(struct pth *); #ifdef THTIME #ifndef NANOSEC /* gcc*/ #define NANOSEC 1000000000 typedef unsigned long long int hrtime_t; unsigned long gethrtime(void) { struct timespec ts; if (clock_gettime(CLOCK_MONOTONIC_RAW, &ts) != 0) return (-1); return ((ts.tv_sec * NANOSEC) + ts.tv_nsec); } #endif #endif #ifdef ANSI_C void MrqmndiagCalc(long ns,long aaN,double *aPr,double* ymPr,double *variancePr,long varianceM,long varianceN, double* ftolPr,double *itMaxPr,double *coefPr,long coefM,long coefN, long womM,double *womPr,double *kd2Pr,long nom,double *omPr, double *aaOutPr,double *chi2Pr,double *itsPr,double *alphaPr,double *pldfvPr,double *pldfvPi,double *physlimPr,double *p_m0,long nion,double *bwomPr,double *fpropPr) #else void MrqmndiagCalc(ns,aaN,aPr,ymPr,variancePr,varianceM,varianceN,ftolPr,itMaxPr,coefPr,coefM,coefN,womM,womPr,kd2Pr,nom,omPr,aaOutPr,chi2Pr,itsPr,alphaPr,pldfvPr,pldfvPi,physlimPr,p_m0,nion,bwomPr,fpropPr) long ns,aaN,varianceM,varianceN,coefM,coefN,womM,nom,nion; double *aPr,*ymPr,*variancePr,*ftolPr,*itMaxPr,*coefPr,*womPr,*kd2Pr,*omPr,*aaOutPr,*chi2Pr,*itsPr,*alphaPr,*pldfvPr,*pldfvPi,*physlimPr,*bwomPr; #endif { unsigned long i,j,nR,nscr,nscr1; double *ya,*dyda,*aa2,*tempYa,*R,*Y,*KhiSqr,*dA,*yaOld,*aaOld; double *tempDyda,*errorBar,*scr,*scr1,*RowStorage; double lambda=0.001,maxDeviation,chi2Old; long validDer=0,its=0,itMax,*indicesVector; long *storage=NULL; unsigned long *varOK,nvarOK,*afree,nafree,nth=1; double *tempAlpha,*plim; unsigned long nag=0,ag[9],nas=0,as[9]; struct pth pth; #ifdef THTIME hrtime_t start1, start2, end1=0, end2=0; start1=gethrtime(); #endif for(i=0;i1) nth=nafree; pthread_attr_t sched_glob; pthread_t *thread; void *retval; if(nth>1) { pthread_attr_init(&sched_glob); pthread_mutex_init(&pth.val_lock,NULL); pthread_attr_setscope(&sched_glob,PTHREAD_SCOPE_SYSTEM); thread=(pthread_t *)calloc(nth,sizeof(pthread_t)); } #endif nscr=(nion+2)*(3+4*nom); nscr1=((nion+1)*5+nom+aaN)*ns; scr=(double *)calloc((nscr+nscr1)*nth,sizeof(double)); scr1=scr+nscr*nth; aa2=(double *)calloc((aaN+(coefM+aaN)*coefN)*nth,sizeof(double)); tempYa=aa2+aaN*nth; DirtheCalc(ns,aaN,aaOutPr,coefPr,womM,womPr,kd2Pr,nom,omPr,pldfvPr,pldfvPi,ya,1,p_m0,nion,bwomPr,scr,scr1); /* Create dyda and the temporaty copy of dyda matrix for the spectrum derivatives */ dyda=(double *)calloc(nvarOK*nafree*2,sizeof(double)); tempDyda=dyda+nvarOK*nafree; /* Copy the sqrt(variance) to the errorbar (for the GULIPS) */ nR=(nafree*(nafree+1))/2; errorBar=(double *)calloc(nvarOK+nR+nafree+1+nafree+1+nafree,sizeof(double)); chi2Pr[0]=0; for (i=0;i1) { pthread_mutex_lock(&pth.val_lock); pth.i=i; pthread_create(&thread[i],&sched_glob,(void *(*)(void *)) dirthe_loop,(void *)(&pth)); } else { pth.i=i; dirthe_loop(&pth); } #else pth.i=i; dirthe_loop(&pth); #endif } #ifdef GUPTHREAD if(nth>1) for(i=0;iplim[IND2(1,j,2)]) aaOutPr[j]=plim[IND2(1,j,2)]; } /* logscale pars IH*/ for(j=0;j=chi2Old) { chi2Pr[0]=chi2Old; for(i=0;i<(coefM+aaN);i++) ya[i]=yaOld[i]; for(i=0;i1) free(thread); #endif } void *dirthe_loop(struct pth *pth) { unsigned long i,j=0; double *aa2,*acf,*scr,*scr1; i=pth->i; #ifdef GUPTHREAD if(pth->nth>1) { pthread_mutex_unlock(&pth->val_lock); j=i; } #endif aa2=j*pth->aaN+pth->aaPr; acf=j*pth->yaSize+pth->acfPr; scr=j*pth->nscr+pth->scr; scr1=j*pth->nscr1+pth->scr1; /*Copy aaOut into aa2*/ for(j=0;jaaN;j++) aa2[j]=pth->aaOutPr[j]; /* Change one of the parameters... */ aa2[pth->afree[i]]+=0.0001; /* ...and calculate the derivatives using DirtheCalc and one loop which calculates the derivative*/ /* logscale pars IH*/ for(j=0;jnag;j++) aa2[pth->ag[j]]=exp(aa2[pth->ag[j]]); for(j=0;jnas;j++) aa2[pth->as[j]]=2.*sinh(aa2[pth->as[j]]); DirtheCalc(pth->ns,pth->aaN,aa2,pth->coefPr,pth->womM,pth->womPr,pth->kd2Pr,pth->nom,pth->omPr,pth->pldfvPr,pth->pldfvPi,acf,0,pth->p_m0,pth->nion,pth->bwomPr,scr,scr1); for(j=0;jnvarOK;j++) pth->dyda[IND2(j,i,pth->nvarOK)]=((pth->ya[pth->varOK[j]]-acf[pth->varOK[j]])/0.0001); return NULL; }