void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { size_t numVertices; double *vertices, A; if(nrhs!=1) { mexErrMsgTxt("Incorrect number of inputs."); return; } if(nlhs>1) { mexErrMsgTxt("Incorrect number of outputs."); return; } checkRealDoubleArray(prhs[0]); //If an empty matrix is passed, return zero area. if(mxIsEmpty(prhs[0])) { const double retVal=0; plhs[0]=doubleMat2Matlab(&retVal,1,1); return; } if(mxGetM(prhs[0])!=2) { mexErrMsgTxt("The points have the wrong dimensionality."); return; } numVertices=mxGetN(prhs[0]); vertices=reinterpret_cast<double*>(mxGetData(prhs[0])); A=signedPolygonAreaCPP(vertices,numVertices); plhs[0]=doubleMat2Matlab(&A,1,1); }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { double R, P, T, wl; double A,B; if(nrhs>4) { mexErrMsgTxt("Incorrect number of inputs."); return; } if(nlhs>2) { mexErrMsgTxt("Wrong number of outputs."); return; } //Get the relative humidity if(nrhs>0&&mxGetM(prhs[0])!=0) { R=getDoubleFromMatlab(prhs[0]); } else {//Otherwise get the value from the Constants class. R=getScalarMatlabClassConst("Constants","standardRelHumid"); } //Get the pressure if(nrhs>1&&mxGetM(prhs[1])!=0) { P=getDoubleFromMatlab(prhs[1]); } else {//Otherwise, get the value from the Constants class. P=getScalarMatlabClassConst("Constants","standardAtmosphericPressure"); } //Get the temperature if(nrhs>2&&mxGetM(prhs[2])!=0) { T=getDoubleFromMatlab(prhs[2]); } else {//Otherwise get the value from the Constants class. T=getScalarMatlabClassConst("Constants","standardTemp"); } //wl is inputted in meters, but needs to be in micrometers for the //function iauAtco13 if(nrhs>3&&mxGetM(prhs[3])!=0) { wl= getDoubleFromMatlab(prhs[3]); } else { wl=0.574e-6; } //Convert from Pascals to millibars. P*=0.01; //Convert from degrees Kelvin to degrees Centigrade. T+=-273.15; //Convert from meters to micrometers. wl*=1e6; //Get the parameters for the simple refraction model. iauRefco(P, T, R, wl,&A, &B); //Allocate space for the return values. plhs[0]=doubleMat2Matlab(&A,1,1); if(nlhs>1) { plhs[1]=doubleMat2Matlab(&B,1,1); } }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { double TT1, TT2, dX, dY, *xVec; size_t numRow, numVec; mxArray *retMat; double *retData; double GCRS2CIRS[3][3]; if(nrhs<3||nrhs>4){ mexErrMsgTxt("Wrong number of inputs"); } if(nlhs>2) { mexErrMsgTxt("Wrong number of outputs."); } checkRealDoubleArray(prhs[0]); numRow = mxGetM(prhs[0]); numVec = mxGetN(prhs[0]); if(!(numRow==3||numRow==6)) { mexErrMsgTxt("The input vector has a bad dimensionality."); } xVec=(double*)mxGetData(prhs[0]); TT1=getDoubleFromMatlab(prhs[1]); TT2=getDoubleFromMatlab(prhs[2]); //If some values from the function getEOP will be needed. if(nrhs<4||mxGetM(prhs[3])==0) { mxArray *retVals[2]; double *dXdY; mxArray *JulUTCMATLAB[2]; double JulUTC[2]; int retVal; //Get the time in UTC to look up the parameters by going to TAI and //then UTC. retVal=iauTttai(TT1, TT2, &JulUTC[0], &JulUTC[1]); if(retVal!=0) { mexErrMsgTxt("An error occurred computing TAI."); } retVal=iauTaiutc(JulUTC[0], JulUTC[1], &JulUTC[0], &JulUTC[1]); switch(retVal){ case 1: mexWarnMsgTxt("Dubious Date entered."); break; case -1: mexErrMsgTxt("Unacceptable date entered"); break; default: break; } JulUTCMATLAB[0]=doubleMat2Matlab(&JulUTC[0],1,1); JulUTCMATLAB[1]=doubleMat2Matlab(&JulUTC[1],1,1); //Get the Earth orientation parameters for the given date. mexCallMATLAB(2,retVals,2,JulUTCMATLAB,"getEOP"); mxDestroyArray(JulUTCMATLAB[0]); mxDestroyArray(JulUTCMATLAB[1]); //%We do not need the polar motion coordinates. mxDestroyArray(retVals[0]); checkRealDoubleArray(retVals[1]); if(mxGetM(retVals[1])!=2||mxGetN(retVals[1])!=1) { mxDestroyArray(retVals[1]); mexErrMsgTxt("Error using the getEOP function."); return; } dXdY=(double*)mxGetData(retVals[1]); dX=dXdY[0]; dY=dXdY[1]; //Free the returned arrays. mxDestroyArray(retVals[1]); } else {//Get the celestial pole offsets size_t dim1, dim2; checkRealDoubleArray(prhs[4]); dim1 = mxGetM(prhs[4]); dim2 = mxGetN(prhs[4]); if((dim1==2&&dim2==1)||(dim1==1&&dim2==2)) { double *dXdY=(double*)mxGetData(prhs[4]); dX=dXdY[0]; dY=dXdY[1]; } else { mexErrMsgTxt("The celestial pole offsets have the wrong dimensionality."); return; } } { double x, y, s; double omega; //Get the X,Y coordinates of the Celestial Intermediate Pole (CIP) and //the Celestial Intermediate Origin (CIO) locator s, using the IAU 2006 //precession and IAU 2000A nutation models. iauXys06a(TT1, TT2, &x, &y, &s); //Add the CIP offsets. x += dX; y += dY; //Get the GCRS-to-CIRS matrix iauC2ixys(x, y, s, GCRS2CIRS); } //Allocate space for the return vectors. retMat=mxCreateDoubleMatrix(numRow,numVec,mxREAL); retData=(double*)mxGetData(retMat); { size_t curVec; for(curVec=0;curVec<numVec;curVec++) { //Multiply the position vector with the rotation matrix. iauRxp(GCRS2CIRS, xVec+numRow*curVec, retData+numRow*curVec); //If a velocity vector was given. if(numRow>3) { double *velGCRS=xVec+numRow*curVec+3;//Velocity in GCRS double *retDataVel=retData+numRow*curVec+3; //Convert velocity from GCRS to CIRS. iauRxp(GCRS2CIRS, velGCRS, retDataVel); } } } plhs[0]=retMat; //If the rotation matrix is desired on the output. if(nlhs>1) { double *elPtr; size_t i,j; plhs[1]=mxCreateDoubleMatrix(3,3,mxREAL); elPtr=(double*)mxGetData(plhs[1]); for (i=0;i<3;i++) { for(j=0;j<3;j++) { elPtr[i+3*j]=GCRS2CIRS[i][j]; } } } }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { const mxArray *MatlabFunctionHandle; direct_algorithm theAlgorithm=DIRECT_ORIGINAL; const direct_objective_func f=&MatlabCallback; size_t numDim; double *lowerBounds; double *upperBounds; int maxFEval=500; int maxIter=100; double epsilon=1e-4; double epsilonAbs=0; double volumeRelTol=1e-10; double sigmaRelTol=0; double fGlobal=DIRECT_UNKNOWN_FGLOBAL; double fGlobalRelTol=DIRECT_UNKNOWN_FGLOBAL; int maxDiv=5000; //To hold return values direct_return_code retVal; double *x; double fVal; if(nrhs<3||nrhs>4){ mexErrMsgTxt("Wrong number of inputs"); } if(nlhs>3) { mexErrMsgTxt("Wrong number of outputs."); } //Check that a function handle was passed. if(!mxIsClass(prhs[0],"function_handle")) { mexErrMsgTxt("The first input must be a function handle."); } MatlabFunctionHandle=prhs[0]; //Check the lower and upper bounds checkRealDoubleArray(prhs[1]); checkRealDoubleArray(prhs[2]); numDim=mxGetM(prhs[1]); if(numDim<1||mxGetN(prhs[1])!=1) { mexErrMsgTxt("The lower bounds have the wrong dimensionality."); } if(mxGetM(prhs[2])!=numDim||mxGetN(prhs[1])!=1) { mexErrMsgTxt("The upper bounds have the wrong dimensionality."); } //The function in the library only uses integers for dimensions. if(numDim>INT_MAX) { mexErrMsgTxt("The problem has too many dimensions to be solved using this function."); } lowerBounds=(double*)mxGetData(prhs[1]); upperBounds=(double*)mxGetData(prhs[2]); //If a structure of options was given if(nrhs>3&&!mxIsEmpty(prhs[3])) { //We have to check for every possible structure member. mxArray *theField; if(!mxIsStruct(prhs[3])) { mexErrMsgTxt("The options must be given in a structure."); } theField=mxGetField(prhs[3],0,"algorithm"); if(theField!=NULL) {//If the field is present. int algType=getIntFromMatlab(theField); //Algorithm type switch(algType) { case 0: theAlgorithm=DIRECT_ORIGINAL; break; case 1: theAlgorithm=DIRECT_GABLONSKY; break; default: mexErrMsgTxt("Invalid algorithm specified"); } } theField=mxGetField(prhs[3],0,"maxDiv"); if(theField!=NULL) {//If the field is present. maxDiv=getIntFromMatlab(theField); if(maxDiv<1) { mexErrMsgTxt("Invalid maxDiv specified"); } } theField=mxGetField(prhs[3],0,"maxIter"); if(theField!=NULL) {//If the field is present. maxIter=getIntFromMatlab(theField); if(maxIter<1) { mexErrMsgTxt("Invalid maxIter specified"); } } theField=mxGetField(prhs[3],0,"maxFEval"); if(theField!=NULL) {//If the field is present. maxFEval=getIntFromMatlab(theField); if(maxIter<1) { mexErrMsgTxt("Invalid maxFEval specified"); } } theField=mxGetField(prhs[3],0,"epsilon"); if(theField!=NULL) {//If the field is present. epsilon=getDoubleFromMatlab(theField); if(fabs(epsilon)>=1) { mexErrMsgTxt("Invalid epsilon specified"); } } theField=mxGetField(prhs[3],0,"epsilonAbs"); if(theField!=NULL) {//If the field is present. epsilonAbs=getDoubleFromMatlab(theField); if(epsilonAbs>=1||epsilonAbs<0) { mexErrMsgTxt("Invalid epsilonAbs specified"); } } theField=mxGetField(prhs[3],0,"volumeRelTol"); if(theField!=NULL) {//If the field is present. volumeRelTol=getDoubleFromMatlab(theField); if(volumeRelTol>=1||volumeRelTol<0) { mexErrMsgTxt("Invalid volumeRelTol specified"); } } theField=mxGetField(prhs[3],0,"sigmaRelTol"); if(theField!=NULL) {//If the field is present. sigmaRelTol=getDoubleFromMatlab(theField); if(sigmaRelTol>=1||sigmaRelTol<0) { mexErrMsgTxt("Invalid sigmaRelTol specified"); } } theField=mxGetField(prhs[3],0,"fGlobal"); if(theField!=NULL) {//If the field is present. fGlobal=getDoubleFromMatlab(theField); fGlobalRelTol=1e-12;//Default value if fGlobal is given. } theField=mxGetField(prhs[3],0,"fGlobalRelTol"); if(theField!=NULL) {//If the field is present. fGlobalRelTol=getDoubleFromMatlab(theField); if(fGlobalRelTol<0) { mexErrMsgTxt("Invalid fGlobalRelTol specified"); } } } //Allocate space for the return values x=mxCalloc(numDim, sizeof(double)); retVal=direct_optimize(f,//Objective function pointer (void*)MatlabFunctionHandle,//Data that passed to the objective function. Here, the function handle passed by the user. (int)numDim,//The dimensionality of the problem lowerBounds,//Array of the lower bound of each dimension. upperBounds,//Array of the upper bound of each dimension. x,//An array that will be set to the optimum value on return. &fVal,//On return, set to the minimum value. maxFEval,//Maximum number of function evaluations. maxIter,//Maximum number of iterations epsilon,//Jones' epsilon parameter (1e-4 is recommended) epsilonAbs,//An absolute version of magic_eps //Relative tolerance on the hypercube volume (use 0 if none). This is //a percentage (0-1) of the volume of the original hypercube volumeRelTol, //Relative tolerance on the hypercube measure (0 if none) sigmaRelTol, //A pointer to a variable that can terminate the optimization. This is //in the library's code so that an external thread can write to this //and force the optimization to stop. Here, we are not using it, so we //can pass NULL. NULL, fGlobal,//Function value of the global optimum, if known. Use DIRECT_UNKNOWN_FGLOBAL if unknown. fGlobalRelTol,//Relative tolerance for convergence if fglobal is known. If unknown, use DIRECT_UNKNOWN_FGLOBAL. NULL,//There is no output to a file. theAlgorithm,//The algorithm to use maxDiv);//The maximum number of hyperrectangle divisions //If an error occurred if(retVal<0) { mxFree(x); switch(retVal){ case DIRECT_INVALID_BOUNDS: mexErrMsgTxt("Upper bounds are <= lower bounds for one or more dimensions."); case DIRECT_MAXFEVAL_TOOBIG: mexErrMsgTxt("maxFEval is too large."); case DIRECT_INIT_FAILED: mexErrMsgTxt("An initialization step failed."); case DIRECT_SAMPLEPOINTS_FAILED: mexErrMsgTxt("An error occurred creating sampling points."); case DIRECT_SAMPLE_FAILED: mexErrMsgTxt("An error occurred while sampling the function."); case DIRECT_OUT_OF_MEMORY: mexErrMsgTxt("Out of memory"); case DIRECT_INVALID_ARGS: mexErrMsgTxt("Invalid arguments provided"); //These errors should not occur either because they should //never be called or because retVal>=0 so these are not //actually errors. case DIRECT_FORCED_STOP: case DIRECT_MAXFEVAL_EXCEEDED: case DIRECT_MAXITER_EXCEEDED: case DIRECT_GLOBAL_FOUND: case DIRECT_VOLTOL: case DIRECT_SIGMATOL: case DIRECT_MAXTIME_EXCEEDED: default: mexErrMsgTxt("An unknown error occurred."); } } //Set the return values plhs[0]=mxCreateNumericMatrix(0, 0, mxDOUBLE_CLASS, mxREAL); mxFree(mxGetPr(plhs[0])); mxSetPr(plhs[0], x); mxSetM(plhs[0], numDim); mxSetN(plhs[0], 1); if(nlhs>1) { plhs[1]=doubleMat2Matlab(&fVal,1,1); if(nlhs>2) { plhs[2]=intMat2MatlabDoubles(&retVal,1,1); } } }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { size_t numRow,numVec; mxArray *retMat; double *xVec, *retData; double TT1, TT2, UT11, UT12; //The if-statements below should properly initialize all of the EOP. //The following initializations to zero are to suppress warnings when //compiling with -Wconditional-uninitialized. double dX=0; double dY=0; double deltaT=0; double LOD=0; double GCRS2TIRS[3][3]; //Polar motion matrix. ITRS=POM*TIRS. We will just be setting it to the //identity matrix as polar motion is not taken into account when going //to the TIRS. double rident[3][3]={{1,0,0},{0,1,0},{0,0,1}}; double Omega[3];//The rotation vector in the TIRS if(nrhs<3||nrhs>6){ mexErrMsgTxt("Wrong number of inputs"); } if(nlhs>2) { mexErrMsgTxt("Wrong number of outputs."); } checkRealDoubleArray(prhs[0]); numRow = mxGetM(prhs[0]); numVec = mxGetN(prhs[0]); if(!(numRow==3||numRow==6)) { mexErrMsgTxt("The input vector has a bad dimensionality."); } xVec=(double*)mxGetData(prhs[0]); TT1=getDoubleFromMatlab(prhs[1]); TT2=getDoubleFromMatlab(prhs[2]); //If some values from the function getEOP will be needed if(nrhs<=5||mxIsEmpty(prhs[3])||mxIsEmpty(prhs[4])||mxIsEmpty(prhs[5])) { mxArray *retVals[5]; double *dXdY; mxArray *JulUTCMATLAB[2]; double JulUTC[2]; int retVal; //Get the time in UTC to look up the parameters by going to TAI and //then UTC. retVal=iauTttai(TT1, TT2, &JulUTC[0], &JulUTC[1]); if(retVal!=0) { mexErrMsgTxt("An error occurred computing TAI."); } retVal=iauTaiutc(JulUTC[0], JulUTC[1], &JulUTC[0], &JulUTC[1]); switch(retVal){ case 1: mexWarnMsgTxt("Dubious Date entered."); break; case -1: mexErrMsgTxt("Unacceptable date entered"); break; default: break; } JulUTCMATLAB[0]=doubleMat2Matlab(&JulUTC[0],1,1); JulUTCMATLAB[1]=doubleMat2Matlab(&JulUTC[1],1,1); //Get the Earth orientation parameters for the given date. mexCallMATLAB(5,retVals,2,JulUTCMATLAB,"getEOP"); mxDestroyArray(JulUTCMATLAB[0]); mxDestroyArray(JulUTCMATLAB[1]); //%We do not need the polar motion coordinates. mxDestroyArray(retVals[0]); checkRealDoubleArray(retVals[1]); if(mxGetM(retVals[1])!=2||mxGetN(retVals[1])!=1) { mxDestroyArray(retVals[1]); mxDestroyArray(retVals[2]); mxDestroyArray(retVals[3]); mxDestroyArray(retVals[4]); mexErrMsgTxt("Error using the getEOP function."); return; } dXdY=(double*)mxGetData(retVals[1]); dX=dXdY[0]; dY=dXdY[1]; //This is TT-UT1 deltaT=getDoubleFromMatlab(retVals[3]); LOD=getDoubleFromMatlab(retVals[4]); //Free the returned arrays. mxDestroyArray(retVals[1]); mxDestroyArray(retVals[2]); mxDestroyArray(retVals[3]); mxDestroyArray(retVals[4]); } //If deltaT=TT-UT1 is given if(nrhs>3&&!mxIsEmpty(prhs[3])) { deltaT=getDoubleFromMatlab(prhs[3]); } //Obtain UT1 from terestrial time and deltaT. iauTtut1(TT1, TT2, deltaT, &UT11, &UT12); //Get celestial pole offsets, if given. if(nrhs>4&&!mxIsEmpty(prhs[4])) { size_t dim1, dim2; checkRealDoubleArray(prhs[4]); dim1 = mxGetM(prhs[4]); dim2 = mxGetN(prhs[4]); if((dim1==2&&dim2==1)||(dim1==1&&dim2==2)) { double *dXdY=(double*)mxGetData(prhs[4]); dX=dXdY[0]; dY=dXdY[1]; } else { mexErrMsgTxt("The celestial pole offsets have the wrong dimensionality."); return; } } //If LOD is given if(nrhs>5&&mxIsEmpty(prhs[5])) { LOD=getDoubleFromMatlab(prhs[5]); } //Compute the rotation matrix for going from GCRS to ITRS as well as //the instantaneous vector angular momentum due to the Earth's rotation //in TIRS coordinates. { double x, y, s, era; double rc2i[3][3]; double omega; //Get the X,Y coordinates of the Celestial Intermediate Pole (CIP) and //the Celestial Intermediate Origin (CIO) locator s, using the IAU 2006 //precession and IAU 2000A nutation models. iauXys06a(TT1, TT2, &x, &y, &s); //Add the CIP offsets. x += dX; y += dY; //Get the GCRS-to-CIRS matrix iauC2ixys(x, y, s, rc2i); //Find the Earth rotation angle for the given UT1 time. era = iauEra00(UT11, UT12); //Set the polar motion matrix to the identity matrix so that the //conversion stops at the TIRS instead of the ITRS. //Combine the GCRS-to-CIRS matrix, the Earth rotation angle, and use //the identity matrix instead of the polar motion matrix to get a //to get the rotation matrix to go from GCRS to TIRS. iauC2tcio(rc2i, era, rident,GCRS2TIRS); //Next, to be able to transform the velocity, the rotation of the Earth //has to be taken into account. //The angular velocity vector of the Earth in the TIRS in radians. omega=getScalarMatlabClassConst("Constants","IERSMeanEarthRotationRate"); //Adjust for LOD omega=omega*(1-LOD/86400.0);//86400.0 is the number of seconds in a TT //day. Omega[0]=0; Omega[1]=0; Omega[2]=omega; } //Allocate space for the return vectors. retMat=mxCreateDoubleMatrix(numRow,numVec,mxREAL); retData=(double*)mxGetData(retMat); { size_t curVec; for(curVec=0;curVec<numVec;curVec++) { //Multiply the position vector with the rotation matrix. iauRxp(GCRS2TIRS, xVec+numRow*curVec, retData+numRow*curVec); //If a velocity vector was given. if(numRow>3) { double *posGCRS=xVec+numRow*curVec; double posTIRS[3]; double *velGCRS=xVec+numRow*curVec+3;//Velocity in GCRS double velTIRS[3]; double *retDataVel=retData+numRow*curVec+3; double rotVel[3]; //If a velocity was provided with the position, first //convert to TIRS coordinates, then account for the //rotation of the Earth. //Convert velocity from GCRS to TIRS. iauRxp(GCRS2TIRS, velGCRS, velTIRS); //Convert position from GCRS to TIRS iauRxp(GCRS2TIRS, posGCRS, posTIRS); //Evaluate the cross product for the angular velocity due //to the Earth's rotation. iauPxp(Omega, posTIRS, rotVel); //Subtract out the instantaneous velocity due to rotation. iauPmp(velTIRS, rotVel, retDataVel); } } } plhs[0]=retMat; //If the rotation matrix is desired on the output. if(nlhs>1) { double *elPtr; size_t i,j; plhs[1]=mxCreateDoubleMatrix(3,3,mxREAL); elPtr=(double*)mxGetData(plhs[1]); for (i=0;i<3;i++) { for(j=0;j<3;j++) { elPtr[i+3*j]=GCRS2TIRS[i][j]; } } } }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { size_t numRow,numVec; mxArray *retMat; double *retData; double ITRS2TIRS[3][3];//Inverse polar motion matrix double *xVec, TT1, TT2; double xp=0; double yp=0;//The polar motion coordinates if(nrhs<3||nrhs>4){ mexErrMsgTxt("Wrong number of inputs"); } if(nlhs>2) { mexErrMsgTxt("Wrong number of outputs."); } numRow = mxGetM(prhs[0]); numVec = mxGetN(prhs[0]); if(!(numRow==3||numRow==6)) { mexErrMsgTxt("The input vector has a bad dimensionality."); } checkRealDoubleArray(prhs[0]); xVec=(double*)mxGetData(prhs[0]); TT1=getDoubleFromMatlab(prhs[1]); TT2=getDoubleFromMatlab(prhs[2]); //If xpyp should be found using the function getEOP. if(nrhs<4||mxIsEmpty(prhs[3])) { mxArray *retVals[1]; double *xpyp; mxArray *JulUTCMATLAB[2]; double JulUTC[2]; int retVal; //Get the time in UTC to look up the parameters by going to TAI and //then UTC. retVal=iauTttai(TT1, TT2, &JulUTC[0], &JulUTC[1]); if(retVal!=0) { mexErrMsgTxt("An error occurred computing TAI."); } retVal=iauTaiutc(JulUTC[0], JulUTC[1], &JulUTC[0], &JulUTC[1]); switch(retVal){ case 1: mexWarnMsgTxt("Dubious Date entered."); break; case -1: mexErrMsgTxt("Unacceptable date entered"); break; default: break; } JulUTCMATLAB[0]=doubleMat2Matlab(&JulUTC[0],1,1); JulUTCMATLAB[1]=doubleMat2Matlab(&JulUTC[1],1,1); //Get the Earth orientation parameters for the given date. mexCallMATLAB(1,retVals,2,JulUTCMATLAB,"getEOP"); mxDestroyArray(JulUTCMATLAB[0]); mxDestroyArray(JulUTCMATLAB[1]); checkRealDoubleArray(retVals[0]); if(mxGetM(retVals[0])!=2||mxGetN(retVals[0])!=1) { mxDestroyArray(retVals[0]); mexErrMsgTxt("Error using the getEOP function."); return; } xpyp=(double*)mxGetData(retVals[0]); xp=xpyp[0]; yp=xpyp[1]; //Free the returned array. mxDestroyArray(retVals[0]); } //Get polar motion coordinates, if given. if(nrhs>3&&!mxIsEmpty(prhs[3])) { size_t dim1, dim2; checkRealDoubleArray(prhs[3]); dim1 = mxGetM(prhs[3]); dim2 = mxGetN(prhs[3]); if((dim1==2&&dim2==1)||(dim1==1&&dim2==2)) { double *xpyp=(double*)mxGetData(prhs[3]); xp=xpyp[0]; yp=xpyp[1]; } else { mexErrMsgTxt("The polar motion coordinates have the wrong dimensionality."); return; } } //Get the rotation matrix from TIRS to ITRS. { double sp; double TIRS2ITRS[3][3];//Polar motion matrix //Get the Terrestrial Intermediate Origin (TIO) locator s' in //radians sp=iauSp00(TT1,TT2); //Get the polar motion matrix iauPom00(xp,yp,sp,TIRS2ITRS); //The inverse polar motion matrix is given by the transpose of the //polar motion matrix. iauTr(TIRS2ITRS, ITRS2TIRS); } //Allocate space for the return vectors. retMat=mxCreateDoubleMatrix(numRow,numVec,mxREAL); retData=(double*)mxGetData(retMat); { size_t curVec; for(curVec=0;curVec<numVec;curVec++) { //Multiply the position vector with the rotation matrix. iauRxp(ITRS2TIRS, xVec+numRow*curVec, retData+numRow*curVec); //Multiply the velocity vector with the rotation matrix. if(numRow>3) { double *velITRS=xVec+numRow*curVec+3;//Velocity in ITRS double *retDataVel=retData+numRow*curVec+3;//Velocity in ITRS //Convert velocity from ITRS to TIRS. iauRxp(ITRS2TIRS, velITRS, retDataVel); } } } plhs[0]=retMat; if(nlhs>1) { double *elPtr; size_t i,j; plhs[1]=mxCreateDoubleMatrix(3,3,mxREAL); elPtr=(double*)mxGetData(plhs[1]); for (i=0;i<3;i++) { for(j=0;j<3;j++) { elPtr[i+3*j]=ITRS2TIRS[i][j]; } } } }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { double TT1,TT2,*xVec; double deltaT=0; double LOD=0; size_t numRow,numVec; double CIRS2TIRS[3][3]; double TIRS2CIRS[3][3]; double Omega[3];//The rotation vector in the TIRS mxArray *retMat; double *retData; if(nrhs<3||nrhs>5){ mexErrMsgTxt("Wrong number of inputs"); } if(nlhs>2) { mexErrMsgTxt("Wrong number of outputs."); } checkRealDoubleArray(prhs[0]); numRow = mxGetM(prhs[0]); numVec = mxGetN(prhs[0]); if(!(numRow==3||numRow==6)) { mexErrMsgTxt("The input vector has a bad dimensionality."); } xVec=(double*)mxGetData(prhs[0]); TT1=getDoubleFromMatlab(prhs[1]); TT2=getDoubleFromMatlab(prhs[2]); //If some values from the function getEOP will be needed if(nrhs<=4||mxIsEmpty(prhs[3])||mxIsEmpty(prhs[4])) { mxArray *retVals[5]; mxArray *JulUTCMATLAB[2]; double JulUTC[2]; int retVal; //Get the time in UTC to look up the parameters by going to TAI and //then UTC. retVal=iauTttai(TT1, TT2, &JulUTC[0], &JulUTC[1]); if(retVal!=0) { mexErrMsgTxt("An error occurred computing TAI."); } retVal=iauTaiutc(JulUTC[0], JulUTC[1], &JulUTC[0], &JulUTC[1]); switch(retVal){ case 1: mexWarnMsgTxt("Dubious Date entered."); break; case -1: mexErrMsgTxt("Unacceptable date entered"); break; default: break; } JulUTCMATLAB[0]=doubleMat2Matlab(&JulUTC[0],1,1); JulUTCMATLAB[1]=doubleMat2Matlab(&JulUTC[1],1,1); //Get the Earth orientation parameters for the given date. mexCallMATLAB(5,retVals,2,JulUTCMATLAB,"getEOP"); mxDestroyArray(JulUTCMATLAB[0]); mxDestroyArray(JulUTCMATLAB[1]); //We do not need the polar motion coordinates. mxDestroyArray(retVals[0]); //We do not need the celestial pole offsets. mxDestroyArray(retVals[1]); //This is TT-UT1 deltaT=getDoubleFromMatlab(retVals[3]); LOD=getDoubleFromMatlab(retVals[4]); //Free the returned arrays. mxDestroyArray(retVals[2]); mxDestroyArray(retVals[3]); mxDestroyArray(retVals[4]); } //If deltaT=TT-UT1 is given if(nrhs>3&&!mxIsEmpty(prhs[3])) { deltaT=getDoubleFromMatlab(prhs[3]); } //If LOD is given if(nrhs>4&&!mxIsEmpty(prhs[4])) { LOD=getDoubleFromMatlab(prhs[4]); } //Compute the rotation matrix for going from CIRS to TIRS as well as //the instantaneous vector angular momentum due to the Earth's rotation //in GCRS coordinates. { double UT11, UT12; double era, omega; //Obtain UT1 from terestrial time and deltaT. iauTtut1(TT1, TT2, deltaT, &UT11, &UT12); //Find the Earth rotation angle for the given UT1 time. era = iauEra00(UT11, UT12); //Construct the rotation matrix. CIRS2TIRS[0][0]=1; CIRS2TIRS[0][1]=0; CIRS2TIRS[0][2]=0; CIRS2TIRS[1][0]=0; CIRS2TIRS[1][1]=1; CIRS2TIRS[1][2]=0; CIRS2TIRS[2][0]=0; CIRS2TIRS[2][1]=0; CIRS2TIRS[2][2]=1; iauRz(era, CIRS2TIRS); //To go from the TIRS to the GCRS, we need to use the inverse rotation //matrix, which is just the transpose of the rotation matrix. iauTr(CIRS2TIRS, TIRS2CIRS); //Next, to be able to transform the velocity, the rotation of the Earth //has to be taken into account. //The angular velocity vector of the Earth in the TIRS in radians. omega=getScalarMatlabClassConst("Constants","IERSMeanEarthRotationRate"); //Adjust for LOD omega=omega*(1-LOD/86400.0);//86400.0 is the number of seconds in a TT //day. Omega[0]=0; Omega[1]=0; Omega[2]=omega; } //Allocate space for the return vectors. retMat=mxCreateDoubleMatrix(numRow,numVec,mxREAL); retData=(double*)mxGetData(retMat); { size_t curVec; for(curVec=0;curVec<numVec;curVec++) { //Multiply the position vector with the rotation matrix. iauRxp(TIRS2CIRS, xVec+numRow*curVec, retData+numRow*curVec); //If a velocity vector was given. if(numRow>3) { double *posTIRS=xVec+numRow*curVec; double *velTIRS=xVec+numRow*curVec+3;//Velocity in GCRS double *retDataVel=retData+numRow*curVec+3; double rotVel[3]; //Evaluate the cross product for the angular velocity due //to the Earth's rotation. iauPxp(Omega, posTIRS, rotVel); //Add the instantaneous velocity due to rotation. iauPpp(velTIRS, rotVel, retDataVel); //Rotate from TIRS to GCRS iauRxp(TIRS2CIRS, retDataVel, retDataVel); } } } plhs[0]=retMat; if(nlhs>1) { double *elPtr; size_t i,j; plhs[1]=mxCreateDoubleMatrix(3,3,mxREAL); elPtr=(double*)mxGetData(plhs[1]); for (i=0;i<3;i++) { for(j=0;j<3;j++) { elPtr[i+3*j]=TIRS2CIRS[i][j]; } } } }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { char cmd[64]; metricTreeCPP *theTree; if(nrhs>4) { mexErrMsgTxt("Too many inputs."); } //Get the command string that is passed. mxGetString(prhs[0], cmd, sizeof(cmd)); //prhs[0] is assumed to be the string telling if(!strcmp("metricTreeCPP", cmd)){ size_t k, N; mxArray *retPtr; k=getSizeTFromMatlab(prhs[1]); N=getSizeTFromMatlab(prhs[2]); theTree = new metricTreeCPP(k,N); //Convert the pointer to a Matlab matrix to return. retPtr=ptr2Matlab<metricTreeCPP*>(theTree); //Lock this mex file so that it can not be cleared until the object //has been deleted (This avoids a memory leak). mexLock(); //Return the pointer to the tree plhs[0]=retPtr; } else if(!strcmp("buildTreeFromBatch",cmd)) { double *dataBatch; //Get the pointer back from Matlab. theTree=Matlab2Ptr<metricTreeCPP*>(prhs[1]); checkRealDoubleArray(prhs[2]); dataBatch=reinterpret_cast<double*>(mxGetData(prhs[2])); theTree->buildTreeFromBatch(dataBatch); } else if(!strcmp("searchRadius",cmd)) { size_t numPoints; ClusterSetCPP<size_t> pointClust; ClusterSetCPP<double> distClust; double *point; double *radius; mxArray *clustParams[3]; //Get the inputs theTree=Matlab2Ptr<metricTreeCPP*>(prhs[1]); checkRealDoubleArray(prhs[2]); checkRealDoubleArray(prhs[3]); point=reinterpret_cast<double*>(mxGetData(prhs[2])); radius=reinterpret_cast<double*>(mxGetData(prhs[3])); numPoints=mxGetN(prhs[2]); if(mxGetM(prhs[2])!=theTree->k){ mexErrMsgTxt("Invalid point size passed."); } //Run the search; rangeCluster now contains the results. theTree->searchRadius(pointClust,distClust,point,radius, numPoints); //Put the results into an instance of the ClusterSet container //class in Matlab. clustParams[0]=unsignedSizeMat2Matlab(pointClust.clusterEls,pointClust.totalNumEl,1); clustParams[1]=unsignedSizeMat2Matlab(pointClust.clusterSizes,pointClust.numClust,1); clustParams[2]=unsignedSizeMat2Matlab(pointClust.offsetArray,pointClust.numClust,1); //Return a ClusterSet containing the appropriate data. mexCallMATLAB(1, &(plhs[0]), 3, clustParams, "ClusterSet"); //If the distances should also be returned. if(nlhs>1) { clustParams[0]=doubleMat2Matlab(distClust.clusterEls,distClust.totalNumEl,1); clustParams[1]=unsignedSizeMat2Matlab(distClust.clusterSizes,distClust.numClust,1); clustParams[2]=unsignedSizeMat2Matlab(distClust.offsetArray,distClust.numClust,1); //Return a ClusterSet containing the appropriate data. mexCallMATLAB(1, &(plhs[1]), 3, clustParams, "ClusterSet"); } } else if(!strcmp("~metricTreeCPP", cmd)){ theTree=Matlab2Ptr<metricTreeCPP*>(prhs[1]); delete theTree; //Unlock the mex file allowing it to be cleared. mexUnlock(); } else if(!strcmp("getAllData", cmd)){ size_t N; size_t k; theTree=Matlab2Ptr<metricTreeCPP*>(prhs[1]); N=theTree->N; k=theTree->k; plhs[0]=unsignedSizeMat2Matlab(theTree->DATAIDX,N, 1); if(nlhs>1) { plhs[1]=signedSizeMat2Matlab(theTree->innerChild,N, 1); if(nlhs>2) { plhs[2]=signedSizeMat2Matlab(theTree->outerChild,N, 1); if(nlhs>3) { plhs[3]=doubleMat2Matlab(theTree->innerRadii,N, 1); if(nlhs>4) { plhs[4]=doubleMat2Matlab(theTree->outerRadii,N, 1); if(nlhs>5) { plhs[5]=doubleMat2Matlab(theTree->data,k, N); } } } } } } else if(!strcmp("getN", cmd)) { theTree=Matlab2Ptr<metricTreeCPP*>(prhs[1]); plhs[0]=unsignedSizeMat2Matlab(&(theTree->N),1,1); } else if(!strcmp("getk", cmd)) { theTree=Matlab2Ptr<metricTreeCPP*>(prhs[1]); plhs[0]=unsignedSizeMat2Matlab(&(theTree->k),1,1); }else { mexErrMsgTxt("Invalid string passed to metricTreeCPPInt."); } }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { double TT1,TT2,TDB1,TDB2,Jul2,deltaTTUT1,deltaT,Jul1UT1, Jul2UT1,UT1Frac; double u, v, elon; int retVal; if(nrhs<2||nrhs>4){ mexErrMsgTxt("Wrong number of inputs."); return; } if(nlhs>2){ mexErrMsgTxt("Wrong number of outputs."); return; } TT1=getDoubleFromMatlab(prhs[0]); TT2=getDoubleFromMatlab(prhs[1]); //If the parameter is given and is not just an empty matrix. if(nrhs>2&&!(mxGetM(prhs[2])==0||mxGetN(prhs[2])==0)) { deltaTTUT1=getDoubleFromMatlab(prhs[2]); } else { mxArray *retVals[4]; mxArray *JulUTCMATLAB[2]; double JulUTC[2]; //Get the time in UTC to look up the parameters by going to TAI and //then UTC. retVal=iauTttai(TT1, TT2, &JulUTC[0], &JulUTC[1]); if(retVal!=0) { mexErrMsgTxt("An error occurred computing TAI."); } retVal=iauTaiutc(JulUTC[0], JulUTC[1], &JulUTC[0], &JulUTC[1]); switch(retVal){ case 1: mexWarnMsgTxt("Dubious Date entered."); break; case -1: mexErrMsgTxt("Unacceptable date entered"); break; default: break; } JulUTCMATLAB[0]=doubleMat2Matlab(&JulUTC[0],1,1); JulUTCMATLAB[1]=doubleMat2Matlab(&JulUTC[1],1,1); //Get the Earth orientation parameters for the given date. mexCallMATLAB(4,retVals,2,JulUTCMATLAB,"getEOP"); //This is TT-UT1 deltaTTUT1=getDoubleFromMatlab(retVals[3]); //Free the returned arrays. mxDestroyArray(retVals[0]); mxDestroyArray(retVals[1]); mxDestroyArray(retVals[2]); mxDestroyArray(retVals[3]); mxDestroyArray(JulUTCMATLAB[0]); mxDestroyArray(JulUTCMATLAB[1]); } if(nrhs>3) { double *xyzClock; if(mxGetM(prhs[3])!=3||mxGetN(prhs[3])!=1) { mexErrMsgTxt("The dimensionality of the clock location is incorrect."); return; } checkRealDoubleArray(prhs[3]); xyzClock=(double*)mxGetData(prhs[3]); //Convert from meters to kilometers. xyzClock[0]/=1000;xyzClock[1]/=1000;xyzClock[2]/=1000; u=sqrt(xyzClock[0]*xyzClock[0] + xyzClock[1]*xyzClock[1]); v=xyzClock[2]; elon=atan2(xyzClock[1],xyzClock[0]); } else { u=0; v=0; elon=0; } //Get UT1 retVal=iauTtut1(TT1, TT2, deltaTTUT1, &Jul1UT1, &Jul2UT1); switch(retVal) { case -1: mexErrMsgTxt("Unacceptable date provided."); return; case 1: mexWarnMsgTxt("Dubious year provided\n"); break; default: break; } //Find the fraction of a Julian day in UT1 UT1Frac=(Jul1UT1-floor(Jul1UT1))+(Jul2UT1-floor(Jul2UT1)); UT1Frac=UT1Frac-floor(UT1Frac); /*Compute TDB-TT. The function iauDtdb takes TDB as an input, but we *only have TT. The documentation for iauDtdb says that TT can be *substituted within the precision limits of the function. However, an *extra iteration is performed here to try to make the result *consistent with TDB2TT to a few more digits of precision.*/ TDB1=TT1; TDB2=TT2; { int curIter; for(curIter=0;curIter<2;curIter++) { deltaT = iauDtdb(TDB1, TDB2, UT1Frac, elon, u, v); //TT -> TDB retVal = iauTttdb(TT1, TT2, deltaT, &TDB1, &TDB2); if(retVal!=0) { mexErrMsgTxt("An error occured during an intermediate conversion to TDB.\n"); return; } } } plhs[0]=doubleMat2Matlab(&TDB1,1, 1); if(nlhs>1) { plhs[1]=doubleMat2Matlab(&TDB2,1, 1); } }
void mexFunction(const int nlhs, mxArray *plhs[], const int nrhs, const mxArray *prhs[]) { size_t numRow, numCol; mxArray *AMat=NULL; double *A,permVal; if(nrhs<1) { mexErrMsgTxt("Not enough inputs."); } if(nrhs>3) { mexErrMsgTxt("Too many inputs."); } if(nlhs>1) { mexErrMsgTxt("Too many outputs."); } numRow = mxGetM(prhs[0]); numCol = mxGetN(prhs[0]); //Empty matrices have a matrix permanent of one by definition. if(numRow==0||numCol==0) { const double retVal=1; plhs[0]=doubleMat2Matlab(&retVal,1,1); return; } checkRealDoubleArray(prhs[0]); //If skip lists have bee provided, then use them. if(nrhs>1) { size_t i, numRowsSkipped,numColsSkipped,numRowsKept,numColsKept; size_t arrayLen; bool *boolColsSkip, *boolRowsSkip; size_t *keptBuffer, *rows2Keep, *cols2Keep; bool didAlloc=false; if(nrhs<3||mxIsEmpty(prhs[2])) { boolColsSkip=reinterpret_cast<bool*>(mxMalloc(numCol*sizeof(bool))); //Set all of the entries to false since no column is skipped. std::fill_n(boolColsSkip, numCol, false); arrayLen=numCol; } else { boolColsSkip=copyBoolArrayFromMatlab(prhs[2], &arrayLen); if(arrayLen!=numCol) { mxFree(boolColsSkip); mexErrMsgTxt("The column skip list has the wrong length."); } } //Count the number of skipped columns numColsSkipped=0; for(i=0; i<numCol; i++) { numColsSkipped+=boolColsSkip[i]; } if(mxIsEmpty(prhs[1])) { boolRowsSkip=reinterpret_cast<bool*>(mxMalloc(numRow*sizeof(bool))); //Set all of the entries to false since no column is skipped. std::fill_n(boolRowsSkip, numRow, false); arrayLen=numRow; } else { boolRowsSkip=copyBoolArrayFromMatlab(prhs[1], &arrayLen); if(arrayLen!=numRow) { mxFree(boolRowsSkip); mexErrMsgTxt("The row skip list has the wrong length."); } } //Count the number of skipped rows numRowsSkipped=0; for(i=0; i<arrayLen; i++) { numRowsSkipped+=boolRowsSkip[i]; } numRowsKept=numRow-numRowsSkipped; numColsKept=numCol-numColsSkipped; //Empty matrices have a matrix permanent of one by definition. if(numRowsKept==0||numColsKept==0) { const double retVal=1; plhs[0]=doubleMat2Matlab(&retVal,1,1); mxFree(boolColsSkip); mxFree(boolRowsSkip); return; } if(numRowsKept<=numColsKept) { A=reinterpret_cast<double*>(mxGetData(prhs[0])); } else { std::swap(numRowsKept, numColsKept); //This is freed using mxDestroyArray AMat=mxCreateDoubleMatrix(numRowsKept,numColsKept,mxREAL); didAlloc=true; mexCallMATLAB(1, &AMat, 1, const_cast<mxArray **>(&prhs[0]), "transpose"); A=reinterpret_cast<double*>(mxGetData(AMat)); } //Set the mapping of indices of the rows in the submatrix to //indices in the full matrix and similarly, set the mapping of //columns in the submatrix to columns in the full matrix. //The two buffers will be allocated in one go and then freed //together in the end. keptBuffer=reinterpret_cast<size_t*>(mxMalloc(sizeof(size_t)*(numRowsKept+numColsKept))); rows2Keep=keptBuffer; cols2Keep=keptBuffer+numRowsKept; { //Do the mapping of the rows. size_t cumSkip, curIdx, curRow; cumSkip=0; curIdx=0; for(curRow=0; curRow<numRow; curRow++) { if(boolRowsSkip[curRow]==true) { cumSkip++; } else { rows2Keep[curIdx]=curIdx+cumSkip; curIdx++; } } } { //Do the mapping of the columns. size_t cumSkip, curIdx, curCol; cumSkip=0; curIdx=0; for(curCol=0; curCol<numCol; curCol++) { if(boolColsSkip[curCol]==true) { cumSkip++; } else { cols2Keep[curIdx]=curIdx+cumSkip; curIdx++; } } } { size_t* buffer; buffer=reinterpret_cast<size_t*>(mxMalloc(numColsKept*sizeof(size_t))); permVal=permCPPSkip(A, numRow, rows2Keep, cols2Keep, numRowsKept, numColsKept,buffer); mxFree(buffer); } //Get rid of temporary space. if(didAlloc) { mxDestroyArray(AMat); } mxFree(keptBuffer); mxFree(boolColsSkip); mxFree(boolRowsSkip); //Set the return value plhs[0]=doubleMat2Matlab(&permVal,1,1); return; } if(numRow==numCol) { double *buffer; A=reinterpret_cast<double*>(mxGetData(prhs[0])); //Allocate temporary scratch space. buffer = reinterpret_cast<double*>(mxMalloc((2*numRow+1)*sizeof(double))); permVal=permSquareCPP(A,numRow,buffer); mxFree(buffer); } else { bool didAlloc=false; size_t *buffer; if(numRow<=numCol) { A=reinterpret_cast<double*>(mxGetData(prhs[0])); } else { std::swap(numRow, numCol); //This is freed using mxDestroyArray AMat=mxCreateDoubleMatrix(numRow,numCol,mxREAL); didAlloc=true; mexCallMATLAB(1, &AMat, 1, const_cast<mxArray **>(&prhs[0]), "transpose"); A=reinterpret_cast<double*>(mxGetData(AMat)); } buffer=reinterpret_cast<size_t*>(mxMalloc(numCol*sizeof(size_t))); permVal=permCPP(A,numRow,numCol,buffer); mxFree(buffer); //Get rid of temporary space. if(didAlloc) { mxDestroyArray(AMat); } } //Set the return value plhs[0]=doubleMat2Matlab(&permVal,1,1); }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { size_t numRow,numVec; mxArray *retMat; double *xVec, *retData; double TT1, TT2, UT11, UT12; //The if-statements below should properly initialize all of the EOP. //The following initializations to zero are to suppress warnings when //compiling with -Wconditional-uninitialized. double xp=0; double yp=0; double deltaT=0; double LOD=0; double ITRS2TEME[3][3]; double PEF2TEME[3][3]; double WInv[3][3];//The inverse polar motion matrix to go from ITRS to PEF. double Omega[3];//The angular velocity vector for the Earth's rotation. if(nrhs<3||nrhs>6){ mexErrMsgTxt("Wrong number of inputs"); } if(nlhs>2) { mexErrMsgTxt("Wrong number of outputs."); return; } checkRealDoubleArray(prhs[0]); numRow = mxGetM(prhs[0]); numVec = mxGetN(prhs[0]); if(!(numRow==3||numRow==6)) { mexErrMsgTxt("The input vector has a bad dimensionality."); } xVec=(double*)mxGetData(prhs[0]); TT1=getDoubleFromMatlab(prhs[1]); TT2=getDoubleFromMatlab(prhs[2]); //If some values from the function getEOP will be needed if(nrhs<6||mxIsEmpty(prhs[3])||mxIsEmpty(prhs[4])||mxIsEmpty(prhs[5])) { mxArray *retVals[5]; double *xpyp; mxArray *JulUTCMATLAB[2]; double JulUTC[2]; int retVal; //Get the time in UTC to look up the parameters by going to TAI and //then UTC. retVal=iauTttai(TT1, TT2, &JulUTC[0], &JulUTC[1]); if(retVal!=0) { mexErrMsgTxt("An error occurred computing TAI."); } retVal=iauTaiutc(JulUTC[0], JulUTC[1], &JulUTC[0], &JulUTC[1]); switch(retVal){ case 1: mexWarnMsgTxt("Dubious Date entered."); break; case -1: mexErrMsgTxt("Unacceptable date entered"); break; default: break; } JulUTCMATLAB[0]=doubleMat2Matlab(&JulUTC[0],1,1); JulUTCMATLAB[1]=doubleMat2Matlab(&JulUTC[1],1,1); //Get the Earth orientation parameters for the given date. mexCallMATLAB(5,retVals,2,JulUTCMATLAB,"getEOP"); mxDestroyArray(JulUTCMATLAB[0]); mxDestroyArray(JulUTCMATLAB[1]); checkRealDoubleArray(retVals[0]); checkRealDoubleArray(retVals[1]); if(mxGetM(retVals[0])!=2||mxGetN(retVals[0])!=1||mxGetM(retVals[1])!=2||mxGetN(retVals[1])!=1) { mxDestroyArray(retVals[0]); mxDestroyArray(retVals[1]); mxDestroyArray(retVals[2]); mxDestroyArray(retVals[3]); mxDestroyArray(retVals[4]); mexErrMsgTxt("Error using the getEOP function."); return; } xpyp=(double*)mxGetData(retVals[0]); xp=xpyp[0]; yp=xpyp[1]; //The celestial pole offsets are not used. //This is TT-UT1 deltaT=getDoubleFromMatlab(retVals[3]); LOD=getDoubleFromMatlab(retVals[4]); //Free the returned arrays. mxDestroyArray(retVals[0]); mxDestroyArray(retVals[1]); mxDestroyArray(retVals[2]); mxDestroyArray(retVals[3]); mxDestroyArray(retVals[4]); } //If deltaT=TT-UT1 is given if(nrhs>3&&!mxIsEmpty(prhs[3])) { deltaT=getDoubleFromMatlab(prhs[3]); } //Obtain UT1 from terestrial time and deltaT. iauTtut1(TT1, TT2, deltaT, &UT11, &UT12); //Get polar motion values, if given. if(nrhs>4&&!mxIsEmpty(prhs[4])) { size_t dim1, dim2; checkRealDoubleArray(prhs[4]); dim1 = mxGetM(prhs[4]); dim2 = mxGetN(prhs[4]); if((dim1==2&&dim2==1)||(dim1==1&&dim2==2)) { double *xpyp=(double*)mxGetData(prhs[4]); xp=xpyp[0]; yp=xpyp[1]; } else { mexErrMsgTxt("The celestial pole offsets have the wrong dimensionality."); return; } } //If LOD is given if(nrhs>5&&!mxIsEmpty(prhs[5])) { LOD=getDoubleFromMatlab(prhs[5]); } { double GMST1982=iauGmst82(UT11, UT12); double TEME2PEF[3][3]; double TEME2ITRS[3][3]; double W[3][3]; double omega; //Get Greenwhich mean sidereal time under the IAU's 1982 model. This //is given in radians and will be used to build a rotation matrix to //rotate into the PEF system. GMST1982=iauGmst82(UT11, UT12); { double cosGMST,sinGMST; cosGMST=cos(GMST1982); sinGMST=sin(GMST1982); //Build the rotation matrix to rotate by GMST about the z-axis. This //will put the position vector in the PEF system. TEME2PEF[0][0]=cosGMST; TEME2PEF[0][1]=sinGMST; TEME2PEF[0][2]=0; TEME2PEF[1][0]=-sinGMST; TEME2PEF[1][1]=cosGMST; TEME2PEF[1][2]=0; TEME2PEF[2][0]=0; TEME2PEF[2][1]=0; TEME2PEF[2][2]=1.0; } //The inverse rotation is just the transpose iauTr(TEME2PEF, PEF2TEME); //To go from PEF to ITRS, we need to build the polar motion matrix //using the IAU's 1980 conventions. { double cosXp,sinXp,cosYp,sinYp; cosXp=cos(xp); sinXp=sin(xp); cosYp=cos(yp); sinYp=sin(yp); W[0][0]=cosXp; W[0][1]=sinXp*sinYp; W[0][2]=sinXp*cosYp; W[1][0]=0; W[1][1]=cosYp; W[1][2]=-sinYp; W[2][0]=-sinXp; W[2][1]=cosXp*sinXp; W[2][2]=cosXp*cosYp; } //The inverse rotation is just the transpose iauTr(W, WInv); //The total rotation matrix is thus the product of the two rotations. //TEME2ITRS=W*TEME2PEF; iauRxr(W, TEME2PEF, TEME2ITRS); //We want the inverse rotation iauTr(TEME2ITRS, ITRS2TEME); //The angular velocity vector of the Earth in the TIRS in radians. omega=getScalarMatlabClassConst("Constants","IERSMeanEarthRotationRate"); //Adjust for LOD omega=omega*(1-LOD/86400.0);//86400.0 is the number of seconds in a TT day. Omega[0]=0; Omega[1]=0; Omega[2]=omega; } //Allocate space for the return vectors. retMat=mxCreateDoubleMatrix(numRow,numVec,mxREAL); retData=(double*)mxGetData(retMat); { size_t curVec; for(curVec=0;curVec<numVec;curVec++) { //Multiply the position vector with the rotation matrix. iauRxp(ITRS2TEME, xVec+numRow*curVec, retData+numRow*curVec); //If a velocity vector was given. if(numRow>3) { double *posITRS=xVec+numRow*curVec; double *velITRS=xVec+numRow*curVec+3;//Velocity in TEME double posPEF[3]; double velPEF[3]; double *retDataVel=retData+numRow*curVec+3; double rotVel[3]; //If a velocity was provided with the position, first //convert to PEF coordinates, then account for the rotation //of the Earth, then rotate into TEME coordinates. //Convert velocity from ITRS to PEF. iauRxp(WInv, velITRS, velPEF); //Convert position from ITRS to PEF iauRxp(WInv, posITRS, posPEF); //Evaluate the cross product for the angular velocity due //to the Earth's rotation. iauPxp(Omega, posPEF, rotVel); //Add the instantaneous velocity due to rotation. iauPpp(velPEF, rotVel, retDataVel); //Rotate from the PEF into the TEME iauRxp(PEF2TEME, retDataVel, retDataVel); } } } plhs[0]=retMat; if(nlhs>1) { double *elPtr; size_t i,j; plhs[1]=mxCreateDoubleMatrix(3,3,mxREAL); elPtr=(double*)mxGetData(plhs[1]); for (i=0;i<3;i++) { for(j=0;j<3;j++) { elPtr[i+3*j]=ITRS2TEME[i][j]; } } } }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { double TT1, TT2, UT11,UT12, deltaT,GMST; int algToUse=2006; int retVal; if(nrhs<2||nrhs>4){ mexErrMsgTxt("Wrong number of inputs."); return; } if(nlhs>1){ mexErrMsgTxt("Wrong number of outputs."); return; } TT1=getDoubleFromMatlab(prhs[0]); TT2=getDoubleFromMatlab(prhs[1]); if(nrhs>2) { algToUse=getIntFromMatlab(prhs[2]); } if(nrhs>3) { deltaT=getDoubleFromMatlab(prhs[3]); } else { mxArray *retVals[4]; mxArray *JulUTCMATLAB[2]; double JulUTC[2]; //Get the time in UTC to look up the parameters by going to TAI and //then UTC. retVal=iauTttai(TT1, TT2, &JulUTC[0], &JulUTC[1]); if(retVal!=0) { mexErrMsgTxt("An error occurred computing TAI."); } retVal=iauTaiutc(JulUTC[0], JulUTC[1], &JulUTC[0], &JulUTC[1]); switch(retVal){ case 1: mexWarnMsgTxt("Dubious Date entered."); break; case -1: mexErrMsgTxt("Unacceptable date entered"); break; default: break; } JulUTCMATLAB[0]=doubleMat2Matlab(&JulUTC[0],1,1); JulUTCMATLAB[1]=doubleMat2Matlab(&JulUTC[1],1,1); //Get the Earth orientation parameters for the given date. mexCallMATLAB(4,retVals,2,JulUTCMATLAB,"getEOP"); //This is TT-UT1 deltaT=getDoubleFromMatlab(retVals[3]); //Free the returned arrays. mxDestroyArray(retVals[0]); mxDestroyArray(retVals[1]); mxDestroyArray(retVals[2]); mxDestroyArray(retVals[3]); mxDestroyArray(JulUTCMATLAB[0]); mxDestroyArray(JulUTCMATLAB[1]); } //Get UT1 retVal=iauTtut1(TT1, TT2, deltaT, &UT11, &UT12); if(retVal!=0) { mexErrMsgTxt("An error occurred computing UT1."); } //Get Greenwhich mean sidereal time in radians using the chosen //algorithm switch(algToUse) { case 1982: GMST=iauGmst82(UT11, UT12); break; case 2000: GMST=iauGmst00(UT11, UT12, TT1, TT2); break; case 2006: GMST=iauGmst06(UT11, UT12, TT1, TT2); break; default: mexErrMsgTxt("An invalid algorithm version was given."); } plhs[0]=doubleMat2Matlab(&GMST,1, 1); }