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;
}
Ejemplo n.º 2
0
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);
// 	}

}
Ejemplo n.º 3
0
void toast::lapack::potri ( char * UPLO, int * N, double * A, int * LDA, int * INFO ) {
  dpotri ( UPLO, N, A, LDA, INFO );
  return;
}