コード例 #1
0
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);
}
コード例 #2
0
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);
    }
}
コード例 #3
0
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];
            }
        }
    }
}
コード例 #4
0
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);
        }
    }
}
コード例 #5
0
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];
            }
        }
    }
}
コード例 #6
0
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];
            }
        }
    }
}
コード例 #7
0
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];
            }
        }
    }
}
コード例 #8
0
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.");
    }
}
コード例 #9
0
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);
    }
}
コード例 #10
0
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);
}
コード例 #11
0
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];
            }
        }
    }
}
コード例 #12
0
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);
}