void TKfit_getPulsarDesignMatrix(double *x,double *y,int n,int nf,void (*fitFuncs)(double, double [], int,pulsar *,int,int), pulsar *psr, int* ip, double **uinv,int ipsr,double ***OUT_designMatrix,double ***OUT_white_designMatrix,double** OUT_b, double** OUT_wb){ //double precision arrays for matrix algebra. double **designMatrix, **white_designMatrix; double basisFunc[nf]; double *b,*white_b; int i,j; int nrows=get_blas_rows(uinv); int ncols=get_blas_cols(uinv); if (ncols!=n){ logmsg("n=%d ncols=%d",n,ncols); logerr("uinv error. Either you did not use malloc_uinv() to create uinv or np!=ncols"); exit(1); } if (nrows!=n && nrows != 1){ logmsg("n=%d nrows=%d",n,nrows); logerr("uinv error. Either you did not use malloc_uinv() to create uinv or np!=nrows"); exit(1); } // double arrays white_designMatrix=malloc_blas(n,nf); designMatrix=malloc_blas(n,nf); b=(double*)malloc(sizeof(double)*n); white_b=(double*)malloc(sizeof(double)*n); /* This routine has been developed from Section 15 in Numerical Recipes */ /* Determine the design matrix - eq 15.4.4 * and the vector 'b' - eq 15.4.5 */ for (i=0;i<n;i++) { // fitFuncs is not threadsafe! fitFuncs(x[i],basisFunc,nf,psr,ip[i],ipsr); for (j=0;j<nf;j++) designMatrix[i][j] = basisFunc[j]; b[i] = y[i]; } // Take into account the data covariance matrix if(nrows==1){ // we have only diagonal elements for (i=0;i<n;i++){ white_b[i]=b[i]*uinv[0][i]; for (j=0;j<nf;j++){ white_designMatrix[i][j] = designMatrix[i][j]*uinv[0][i]; } } } else { TKmultMatrix_sq(uinv,designMatrix,n,nf,white_designMatrix); TKmultMatrixVec_sq(uinv,b,n,white_b); } *OUT_designMatrix=designMatrix; *OUT_white_designMatrix=white_designMatrix; *OUT_b=b; *OUT_wb=white_b; }
/* * Derive a covariance matrix from the given filename. * * input: * univ (double[np][np] empty matrix that will be filled with the "Cholesky matrix" * fname (char[*]) Input filename to read * psr (*pulsar) pointer to pulsar structure that univ is used for * resx (double[np]) X values of residuals (+ 0 for constraints) * resy (double[np]) Y values of residuals (+ 0 for constraints) * rese (double[np]) Error on residuals (+ eta for constraints) * np (int) Number of data points in fit (nres+nc) * nc (int) Number of constraints in fit * ip (int) Mapping from fit point to observation number in pulsar struct. */ void getCholeskyMatrix(double **uinv, char* fname, pulsar *psr, double *resx,double *resy,double *rese, int np, int nc,int* ip){ FILE* modelDescriptionFile; char modelFileName[1024]; char tmp[1024]; double **m; int i,j; int nrows=get_blas_rows(uinv); int ncols=get_blas_cols(uinv); if (ncols!=np){ logmsg("np=%d ncols=%d",ncols,np); logerr("uinv error. Either you did not use malloc_uinv() to create uinv or np!=ncols"); exit(1); } if (nrows==1){ // we are just adding the errors to a diagonal matrix. getCholeskyDiagonals(uinv,psr,resx,resy, rese, np, nc,ip); return; } if (nrows!=np){ logmsg("np=%d nrows=%d",ncols,np); logerr("uinv error. Either you did not use malloc_uinv() to create uinv or np!=nrows"); exit(1); } if(uinv[np-1] != uinv[0]+(np-1)*np){ logerr("uinv matrix not declared as consecutive memory."); logmsg("Please use malloc_uinv() and free_uinv() from cholesky.C"); #ifdef ACCEL_UINV // if we are using the accelerated code then it will crash... otherwise it's just a warning exit(1); #endif } logmsg("Reading Cholesky model '%s' for pulsar %s",fname,psr->name); m=(double**)malloc(sizeof(double*)*(np+1)); if(!m)logerr("Could not allocate enough memory"); for(i=0;i<np+1;i++){ m[i]=(double*)malloc(sizeof(double)*(np+1)); if(!m[i])logerr("Could not allocate enough memory"); } if (strcmp(fname,"PSRJ")==0){ // this is the old method where the covariance function is read based on pulsar name. // There is no model description file. // This method is depricated logdbg("Reading covariance function using 'PSRJ' is now depricated"); sprintf(modelFileName,"covarFunc.dat_%s",psr->name); cholesky_readFromCovarianceFunction(m,modelFileName,resx,resy,rese,np,nc); } else { cholesky_readT2CholModel(m,fname,resx,resy,rese,np,nc,ip,psr); } if(psr->ToAextraCovar!=NULL){ logmsg("adding extra covar function to m"); for (i=0;i<np;i++) { for (j=0;j<np;j++){ m[i][j]+=psr->ToAextraCovar[i][j]; } } } logdbg("mbefore = "); for (i=0;i<5;i++) { for (j=0;j<5;j++) fprintf(LOG_OUTFILE,"%10g ",m[i][j]); fprintf(LOG_OUTFILE,"\n"); } fprintf(LOG_OUTFILE,"\n"); // make sure constraints are not covariant with anything. logdbg("Ensuring constraints have zero co-variance, np = %d, nc = %d",np,nc); for (i=np-nc; i < np; i++){ for (j=0; j < np; j++){ m[i][j]=0; m[j][i]=0; } } logdbg("Adding errors"); for(i=0;i<np;i++){ m[i][i]+=rese[i]*rese[i]; } if (debugFlag) { logdbg("m = "); for (i=0;i<5;i++) { for (j=0;j<5;j++) fprintf(LOG_OUTFILE,"%10g ",m[i][j]); fprintf(LOG_OUTFILE,"\n"); } fprintf(LOG_OUTFILE,"\n"); FILE* mFile = fopen("chol.covarMatrix","w"); for (i=0;i<np;i++) { for (j=0;j<np;j++) fprintf(mFile,"%d %d %g\n",i,j,m[i][j]); fprintf(mFile,"\n"); } fclose(mFile); } logdbg("Form uinv from cholesky matrix 'm'"); int ret = cholesky_formUinv(uinv,m,np); if (ret!=0) { logerr("Error with formUinv"); exit(ret); } for(i=0;i<np+1;i++)free(m[i]); free(m); }