void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { mwIndex i, j; /* indeces for populating lower triangle when finished. */ mwSize n; /* Size of the matrix. */ mwSignedIndex info; /* flag for success in dpotrf, spotrf, dpotri, spotri */ char *uplo = "U"; /* upper or lower triangle */ mxClassID type; /* array type */ /* If we don't pass in the correct number of arguments, throw error. */ if (nrhs!=1) { mexErrMsgIdAndTxt("mexFunction:invChol_mex:numInputs", "1 input required: A (square matrix)"); } type = mxGetClassID(prhs[0]); /* get the array type */ n = mxGetM(prhs[0]); /* input matrix dimension */ /* check for symmetric matrix*/ if (n!=mxGetN(prhs[0])) { mexErrMsgIdAndTxt("MATLAB:invChol_mex:matchdims", "matrix is not symmetric"); } /* create output matrix (fortran modifies the input so we need to copy the input to output) */ plhs[0]=mxDuplicateArray(prhs[0]); /* If we passed in an empty return an empty. */ if (n==0) { return; } /* double precision */ if(type==mxDOUBLE_CLASS) { double *B; /* double pointer to input & output matrices*/ B = mxGetPr(plhs[0]); /* output matrix pointer */ dpotrf( uplo, &n, B, &n, &info ); /* Double Cholesky decomposition */ /* check for success */ if (info<0) { mexErrMsgIdAndTxt("MATLAB:invChol_mex:dpotrf:illegalvalue", "cholesky decomposition failed: illegal value "); } if (info>0) { mexErrMsgIdAndTxt("MATLAB:invChol_mex:dpotrf:notposdef", "cholesky decomposition failed: matrix is not positive definite"); } dpotri( uplo, &n, B, &n, &info ); /* Double Inverse using Cholesky decomposition */ /* check for success */ if (info<0) { mexErrMsgIdAndTxt("MATLAB:invChol_mex:dpotri:illegalvalue", "failed to invert: illegal value"); } if (info>0) { mexErrMsgIdAndTxt("MATLAB:invChol_mex:dpotri:singularmatrix", "failed to invert: a diagonal element was 0"); } /* populate the lower triangle */ for (i=0; i<n; i++) { for (j=i+1; j<n; j++) { B[n*i+j]=B[j*n+i]; } } } else if (type==mxSINGLE_CLASS) { float *B; /* float pointer to input and output matrices */ B = (float*) mxGetData(plhs[0]); /* output matrix pointer */ spotrf( uplo, &n, B, &n, &info ); /* Double Cholesky decomposition */ /* check for success */ if (info<0) { mexErrMsgIdAndTxt("MATLAB:invChol_mex:spotrf:illegalvalue", "cholesky decomposition failed: illegal value "); } if (info>0) { mexErrMsgIdAndTxt("MATLAB:invChol_mex:spotrf:notposdef", "cholesky decomposition failed: matrix is not positive definite"); } spotri( uplo, &n, B, &n, &info ); /* Double Inverse using Cholesky decomposition */ /* check for success */ if (info<0) { mexErrMsgIdAndTxt("MATLAB:invChol_mex:spotri:illegalvalue", "failed to invert: illegal value"); } if (info>0) { mexErrMsgIdAndTxt("MATLAB:invChol_mex:spotri:singularmatrix", "failed to invert: a diagonal element was 0"); } /* populate the lower triangle*/ for (i=0; i<n; ++i) { for (j=i+1; j<n; ++j) { B[n*i+j]=B[j*n+i]; } } } else { mexErrMsgIdAndTxt("MATLAB:invChol_mex:illegaltype", "only single or double matrix inputs are allowed"); } return; }
void LRedMarginLinearLogLike(double *Cube, int &ndim, int &npars, double &lnew, void *context) { int numfit=((MNStruct *)context)->numFitTiming + ((MNStruct *)context)->numFitJumps+1; double Fitparams[numfit]; double *EFAC; double EQUAD; int pcount=0; // printf("here1\n"); for(int p=0;p<ndim;p++){ // printf("param %i %g %g\n",p,((MNStruct *)context)->Dpriors[p][0],((MNStruct *)context)->Dpriors[p][1]); Cube[p]=(((MNStruct *)context)->Dpriors[p][1]-((MNStruct *)context)->Dpriors[p][0])*Cube[p]+((MNStruct *)context)->Dpriors[p][0]; } // printf("here1.5\n"); for(int p=0;p < numfit; p++){ Fitparams[p]=Cube[p]; pcount++; // printf("param: %i %g \n",p,Fitparams[p]); } if(((MNStruct *)context)->numFitEFAC == 0){ EFAC=new double[1]; EFAC[0]=1; // } else if(((MNStruct *)context)->numFitEFAC == 1){ EFAC=new double[1]; EFAC[0]=Cube[pcount]; pcount++; } else if(((MNStruct *)context)->numFitEFAC > 1){ EFAC=new double[((MNStruct *)context)->numFitEFAC]; for(int p=0;p< ((MNStruct *)context)->numFitEFAC; p++){ EFAC[p]=Cube[pcount]; pcount++; } } if(((MNStruct *)context)->numFitEQUAD == 0){ EQUAD=0; // printf("EQUAD: %g \n",EQUAD); } else{ EQUAD=pow(10.0,2*Cube[pcount]); pcount++; // printf("EQUAD: %g %g %g %i \n",EQUAD,EQUADPrior[0],EQUADPrior[1],((MNStruct *)context)->numFitTiming + ((MNStruct *)context)->numFitJumps + ((MNStruct *)context)->numFitEFAC); } double *Fitvec=new double[((MNStruct *)context)->pulse->nobs]; double *Diffvec=new double[((MNStruct *)context)->pulse->nobs]; dgemv(((MNStruct *)context)->DMatrix,Fitparams,Fitvec,((MNStruct *)context)->pulse->nobs,numfit,'N'); for(int o=0;o<((MNStruct *)context)->pulse->nobs; o++){ Diffvec[o]=((MNStruct *)context)->pulse->obsn[o].residual-Fitvec[o]; } int FitCoeff=2*(((MNStruct *)context)->numFitRedCoeff); double *powercoeff=new double[FitCoeff]; double *Noise=new double[((MNStruct *)context)->pulse->nobs]; double *GDiffvec=new double[((MNStruct *)context)->Gsize]; for(int o=0;o<((MNStruct *)context)->pulse->nobs; o++){ Noise[o]=pow(((((MNStruct *)context)->pulse->obsn[o].toaErr)*pow(10.0,-6))*EFAC[((MNStruct *)context)->sysFlags[o]],2) + EQUAD; } double **NG = new double*[((MNStruct *)context)->pulse->nobs]; for (int k=0; k<((MNStruct *)context)->pulse->nobs; k++) NG[k] = new double[((MNStruct *)context)->Gsize]; for(int i=0;i<((MNStruct *)context)->pulse->nobs;i++){ for(int j=0;j<((MNStruct *)context)->Gsize; j++){ NG[i][j]=((MNStruct *)context)->GMatrix[i][j]*Noise[i]; } } double** GG = new double*[((MNStruct *)context)->Gsize]; for (int k=0; k<((MNStruct *)context)->Gsize; k++) GG[k] = new double[((MNStruct *)context)->Gsize]; dgemm(((MNStruct *)context)->GMatrix, NG,GG,((MNStruct *)context)->pulse->nobs, ((MNStruct *)context)->Gsize,((MNStruct *)context)->pulse->nobs, ((MNStruct *)context)->Gsize, 'T','N'); double tdet=0; dpotrf(GG, ((MNStruct *)context)->Gsize, tdet); dpotri(GG,((MNStruct *)context)->Gsize); dgemm(((MNStruct *)context)->GMatrix, GG,NG,((MNStruct *)context)->pulse->nobs, ((MNStruct *)context)->Gsize, ((MNStruct *)context)->Gsize, ((MNStruct *)context)->Gsize, 'N','N'); double **GNG = new double*[((MNStruct *)context)->pulse->nobs]; for (int k=0; k<((MNStruct *)context)->pulse->nobs; k++) GNG[k] = new double[((MNStruct *)context)->pulse->nobs]; dgemm(NG, ((MNStruct *)context)->GMatrix, GNG,((MNStruct *)context)->pulse->nobs, ((MNStruct *)context)->Gsize, ((MNStruct *)context)->pulse->nobs, ((MNStruct *)context)->Gsize, 'N','T'); double timelike=0; for(int o1=0; o1<((MNStruct *)context)->pulse->nobs; o1++){ for(int o2=0;o2<((MNStruct *)context)->pulse->nobs; o2++){ timelike=timelike+Diffvec[o1]*GNG[o1][o2]*Diffvec[o2]; } } double *NFd = new double[FitCoeff]; double **FMatrix=new double*[((MNStruct *)context)->pulse->nobs]; for(int i=0;i<((MNStruct *)context)->pulse->nobs;i++){ FMatrix[i]=new double[FitCoeff]; } double **NF=new double*[((MNStruct *)context)->pulse->nobs]; for(int i=0;i<((MNStruct *)context)->pulse->nobs;i++){ NF[i]=new double[FitCoeff]; } double **FNF=new double*[FitCoeff]; for(int i=0;i<FitCoeff;i++){ FNF[i]=new double[FitCoeff]; } double start,end; int go=0; for (int i=0;i<((MNStruct *)context)->pulse->nobs;i++) { if (((MNStruct *)context)->pulse->obsn[i].deleted==0) { if (go==0) { go = 1; start = (double)((MNStruct *)context)->pulse->obsn[i].bat; end = start; } else { if (start > (double)((MNStruct *)context)->pulse->obsn[i].bat) start = (double)((MNStruct *)context)->pulse->obsn[i].bat; if (end < (double)((MNStruct *)context)->pulse->obsn[i].bat) end = (double)((MNStruct *)context)->pulse->obsn[i].bat; } } } // printf("Total time span = %.6f days = %.6f years\n",end-start,(end-start)/365.25); double maxtspan=end-start; double freqdet=0; for (int i=0; i<FitCoeff/2; i++){ int pnum=pcount; double pc=Cube[pcount]; powercoeff[i]=pow(10.0,pc)/(maxtspan*24*60*60);///(365.25*24*60*60)/4; powercoeff[i+FitCoeff/2]=powercoeff[i]; freqdet=freqdet+2*log(powercoeff[i]); pcount++; } int coeffsize=FitCoeff/2; std::vector<double>freqs(FitCoeff/2); for(int i=0;i<FitCoeff/2;i++){ freqs[i]=double(i+1)/maxtspan; } for(int i=0;i<FitCoeff/2;i++){ for(int k=0;k<((MNStruct *)context)->pulse->nobs;k++){ double time=(double)((MNStruct *)context)->pulse->obsn[k].bat; //- (double)((MNStruct *)context)->pulse->param[param_pepoch].val[0] - maxtspan/2; FMatrix[k][i]=cos(2*M_PI*freqs[i]*time); // printf("cos %i %i %g \n",i,k,time); } } for(int i=0;i<FitCoeff/2;i++){ for(int k=0;k<((MNStruct *)context)->pulse->nobs;k++){ double time=(double)((MNStruct *)context)->pulse->obsn[k].bat; //- (double)((MNStruct *)context)->pulse->param[param_pepoch].val[0] - maxtspan/2; FMatrix[k][i+FitCoeff/2]=sin(2*M_PI*freqs[i]*time); // printf("sin %i %i %g \n",i+FitCoeff/2,k,time); } } dgemm(GNG, FMatrix , NF, ((MNStruct *)context)->pulse->nobs,((MNStruct *)context)->pulse->nobs, ((MNStruct *)context)->pulse->nobs, FitCoeff, 'N', 'N'); dgemm(FMatrix, NF , FNF, ((MNStruct *)context)->pulse->nobs, FitCoeff, ((MNStruct *)context)->pulse->nobs, FitCoeff, 'T', 'N'); dgemv(NF,Diffvec,NFd,((MNStruct *)context)->pulse->nobs,FitCoeff,'T'); double **PPFM=new double*[FitCoeff]; for(int i=0;i<FitCoeff;i++){ PPFM[i]=new double[FitCoeff]; for(int j=0;j<FitCoeff;j++){ PPFM[i][j]=0; } } for(int c1=0; c1<FitCoeff; c1++){ PPFM[c1][c1]=1.0/powercoeff[c1]; } for(int j=0;j<FitCoeff;j++){ for(int k=0;k<FitCoeff;k++){ PPFM[j][k]=PPFM[j][k]+FNF[j][k]; } } double jointdet=0; dpotrf(PPFM, FitCoeff, jointdet); dpotri(PPFM,FitCoeff); double freqlike=0; for(int i=0;i<FitCoeff;i++){ for(int j=0;j<FitCoeff;j++){ // printf("%i %i %g %g\n",i,j,NFd[i],PPFM[i][j]); freqlike=freqlike+NFd[i]*PPFM[i][j]*NFd[j]; } } lnew=-0.5*(tdet+jointdet+freqdet+timelike-freqlike); if(isnan(lnew) || isinf(lnew)){ lnew=-pow(10.0,200); // printf("red amp and alpha %g %g\n",redamp,redalpha); // printf("Like: %g %g %g \n",lnew,Chisq,covdet); } delete[] EFAC; delete[] powercoeff; delete[] NFd; for (int j = 0; j < FitCoeff; j++){ delete[]PPFM[j]; } delete[]PPFM; for (int j = 0; j < ((MNStruct *)context)->pulse->nobs; j++){ delete[]NF[j]; } delete[]NF; for (int j = 0; j < FitCoeff; j++){ delete[]FNF[j]; } delete[]FNF; for (int j = 0; j < ((MNStruct *)context)->pulse->nobs; j++){ delete[]FMatrix[j]; } delete[]FMatrix; delete[] Noise; delete[] Diffvec; delete[] Fitvec; for (int j = 0; j < ((MNStruct *)context)->pulse->nobs; j++){ delete[] NG[j]; } delete[] NG; for (int j = 0; j < ((MNStruct *)context)->Gsize; j++){ delete[]GG[j]; } delete[] GG; for (int j = 0; j < ((MNStruct *)context)->pulse->nobs; j++){ delete[] GNG[j]; } delete[] GNG; // if(isinf(lnew) || isinf(jointdet) || isinf(tdet) || isinf(freqdet) || isinf(timelike) || isinf(freqlike)){ // printf("Chisq: %g %g %g %g %g %g \n",lnew,jointdet,tdet,freqdet,timelike,freqlike); // } }
void toast::lapack::potri ( char * UPLO, int * N, double * A, int * LDA, int * INFO ) { dpotri ( UPLO, N, A, LDA, INFO ); return; }