//usage:feature = feaGen( training,depth,ndim);
//state:finishing
//version:v1
//notation: maximum size of buffer is 1024
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, mxArray * prhs[])
{
	// check the input parameter
	if (nlhs != 1)
		mexErrMsgTxt(" error in using feaGen, one output is needed");
	if (nrhs != 3)
		mexErrMsgTxt(" error in using feaGen, three input are needed");
	if (!mxIsCell(prhs[0]))
	{
		mexErrMsgTxt(" input type error");
	}

	mxArray * pp, *ptemp;
	mwSize M;
	mwSize depth, ndim;
	int i, j, k, m, n, intTemp;
	double *pointer;

	//get parameter
	depth = mxGetScalar(prhs[1]);
	ndim = mxGetScalar(prhs[2]);
	M = mxGetM(prhs[0]);
	//alloc the space

	char *buf = (char*) mxMalloc((unsigned int) (MAXSIZE) * sizeof(char));

	char ** fea;
	fea = (char**) mxMalloc((unsigned int) ndim * sizeof(char*));
	for (i = 0; i < ndim; i++)
	{
		fea[i] = (char*) mxMalloc((unsigned int) (MAXSIZE) * sizeof(char));
	}

	feature fv(ndim, depth, M);

	for (i = 0; i < M; i++)
	{
		fv.addLine();
		ptemp = mxGetCell(prhs[0], i);
		if (mxGetString(ptemp, buf, (unsigned int) MAXSIZE))
			mexErrMsgTxt("error in the buffer of this function:line53");
#ifdef debug
		mexPrintf("%s",buf);
#endif
		for (j = 0; buf[j] != '\0'; j++)
		{
			intTemp = char2num(buf[j]);
			for (int l = 0; l < ndim; l++)
			{

				fea[l][j] = (int)(intTemp & 0x1) + '0';
				intTemp >>= 1;
			}
		}

		int len = j;
#ifdef debug
		mexPrintf("%s",len);
#endif
		char *temp;
		temp = (char*) mxMalloc((ndim * depth + 1) * sizeof(char));
		for (j = 0; j <= len - depth; j++)
		{
			intTemp = 0;
			int mm, nn;
			for (nn = 0; nn < ndim; nn++)
			{
				for (mm = 0; mm < depth; mm++)
				{
					temp[intTemp++] = fea[nn][mm + j];
				}
			}
			*(temp + ndim * depth) = '\0';
			intTemp = ndim * depth;
			int index = to2num(temp, intTemp);
			if( index < 0 || index > power2(ndim,depth))
			{
				mexErrMsgTxt("error in input format line:90");
			}
			fv.store(index);
		}
		mxFree(temp);

	}

	mxFree(buf);
	for (i = 0; i < ndim; i++)
	{
		mxFree(fea[i]);
	}
	mxFree(fea);

	int lineSize = fv.getLineSize();
	plhs[0] = mxCreateDoubleMatrix(fv.getLen(), lineSize, mxREAL);
	pointer = mxGetPr(plhs[0]);
	fv.transaction(pointer);

}
void mexFunction(int nlhs, mxArray *plhs[],
                 int nrhs, const mxArray *prhs[])
{
    /* Declaration of input and output arguments. */
    double *x, *u, **p, *dx, *y, *t;
    int     i, np, nu, nx;
    const mxArray *auxvar = NULL; /* Cell array of additional data. */
    
    if (nrhs < 3) {
        mexErrMsgIdAndTxt("IDNLGREY:ODE_FILE:InvalidSyntax",
        "At least 3 inputs expected (t, u, x).");
    }
    
    /* Determine if auxiliary variables were passed as last input.  */
    if ((nrhs > 3) && (mxIsCell(prhs[nrhs-1]))) {
        /* Auxiliary variables were passed as input. */
        auxvar = prhs[nrhs-1];
        np = nrhs - 4; /* Number of parameters (could be 0). */
    } else {
        /* Auxiliary variables were not passed. */
        np = nrhs - 3; /* Number of parameters. */
    }
    
    /* Determine number of inputs and states. */
    nx = mxGetNumberOfElements(prhs[1]); /* Number of states. */
    nu = mxGetNumberOfElements(prhs[2]); /* Number of inputs. */
    
    /* Obtain double data pointers from mxArrays. */
    t = mxGetPr(prhs[0]);  /* Current time value (scalar). */
    x = mxGetPr(prhs[1]);  /* States at time t. */
    u = mxGetPr(prhs[2]);  /* Inputs at time t. */
    
    p = mxCalloc(np, sizeof(double*));
    for (i = 0; i < np; i++) {
        p[i] = mxGetPr(prhs[3+i]); /* Parameter arrays. */
    }
    
    /* Create matrix for the return arguments. */
    plhs[0] = mxCreateDoubleMatrix(nx, 1, mxREAL);
    plhs[1] = mxCreateDoubleMatrix(NY, 1, mxREAL);
    dx      = mxGetPr(plhs[0]); /* State derivative values. */
    y       = mxGetPr(plhs[1]); /* Output values. */
    
    /*
      Call the state and output update functions.
      
      Note: You may also pass other inputs that you might need,
      such as number of states (nx) and number of parameters (np).
      You may also omit unused inputs (such as auxvar).
      
      For example, you may want to use orders nx and nu, but not time (t)
      or auxiliary data (auxvar). You may write these functions as:
          compute_dx(dx, nx, nu, x, u, p);
          compute_y(y, nx, nu, x, u, p);
    */
    
    /* Call function for state derivative update. */
    compute_dx(dx, t[0], x, u, p, auxvar);
    
    /* Call function for output update. */
    compute_y(y, t[0], x, u, p, auxvar);
    
    /* Clean up. */
    mxFree(p);
}
Esempio n. 3
0
//Main Function
void mexFunction(int nlhs, mxArray *plhs[],int nrhs, const mxArray *prhs[])
{
    //Input Args
    double *f, *A = NULL, *b = NULL, *lb = NULL, *ub = NULL, *y0 = NULL;
    double *sdpDIM = NULL, *SDP_pr = NULL;
    
    //Return Args
    double *x, *pval, *dval, *exitflag, *iter, *pdflag;
    
    //Options (most get defaults written in)
    int maxiter = 1500;  
    int reuse=4,rpos=0,drho=1,ndim,sdpnmax=1;
    double penalty,rho,dbound,dlbound,zbar,r0,mu0,ylow,yhigh,gaptol,pnormtol,maxtrust,steptol,inftol,infptol;
    double lpb=1.0, datanorm[3], *dreuse, *fixed = NULL;
    
    //Internal Vars
    size_t nlincon = 0, ndec = 0, ncones = 0, nfix = 0;
    size_t lincon_nz = 0;    
    size_t i, j;
    size_t nLB = 0, nUB = 0;
    int *temp_ir = NULL, *temp_jc = NULL;
    double *temp_pr = NULL;
    const char *onames[2] = {"pval","dval"};
    const char *fnames[11] = {"iter","pdflag","r","mu","pstep","dstep","pnorm","ynorm","tracex","reuse","rho"};    
    double evaltime, *X = NULL;
    int iters = 0, status, indcell = 0;
    
    //DSDP Vars
    DSDP dsdp;
    SDPCone sdpcone = NULL;
    LPCone lpcone   = NULL;
    BCone bcone     = NULL;
    DSDPTerminationReason reason;
    DSDPSolutionType pdfeasible;  

    //Sparse Indicing
    mwIndex *A_ir, *A_jc;
    //Version Return
    if(nrhs < 1) {
        if(nlhs < 1)
            printSolverInfo();
        else
            plhs[0] = mxCreateString(DSDP_VERSION);
        return;
    }        
    
    //Check Inputs
    checkInputs(prhs,nrhs); 
    
    //Get pointers to Input variables
	f = mxGetPr(pF); ndec = mxGetNumberOfElements(pF);
    if(!mxIsEmpty(pA)) {
        A = mxGetPr(pA); 
        A_ir = mxGetIr(pA);
        A_jc = mxGetJc(pA);
        b = mxGetPr(pB);
        nlincon = mxGetM(pA);
        lincon_nz = A_jc[mxGetN(pA)];
    }
    if(nrhs > eLB && !mxIsEmpty(pLB))
        lb = mxGetPr(pLB); 
    if(nrhs > eUB && !mxIsEmpty(pUB))
        ub = mxGetPr(pUB);
    if(nrhs > eSDP && !mxIsEmpty(pSDP)) {
        if(mxIsCell(pSDP))
            ncones = mxGetNumberOfElements(pSDP);
        else
            ncones = 1;
    }
    if(nrhs > eY0 && !mxIsEmpty(pY0))
        y0 = mxGetPr(pY0);
    if(nrhs > eOPTS && !mxIsEmpty(pOPTS) && mxGetField(pOPTS,0,"fixed") && !mxIsEmpty(mxGetField(pOPTS,0,"fixed"))) {
        fixed = mxGetPr(mxGetField(pOPTS,0,"fixed"));
        nfix = mxGetM(mxGetField(pOPTS,0,"fixed")); 
    }
    
    //Create Outputs
    plhs[0] = mxCreateDoubleMatrix(ndec,1, mxREAL);
    plhs[1] = mxCreateStructMatrix(1,1,2,onames);
    mxSetField(plhs[1],0,onames[0],mxCreateDoubleMatrix(1,1, mxREAL));
    mxSetField(plhs[1],0,onames[1],mxCreateDoubleMatrix(1,1, mxREAL));
    plhs[2] = mxCreateDoubleMatrix(1,1, mxREAL);   
    x = mxGetPr(plhs[0]); 
    pval = mxGetPr(mxGetField(plhs[1],0,onames[0]));
    dval = mxGetPr(mxGetField(plhs[1],0,onames[1]));
    exitflag = mxGetPr(plhs[2]);    
    //Info Output    
    plhs[3] = mxCreateStructMatrix(1,1,11,fnames);
    mxSetField(plhs[3],0,fnames[0],mxCreateDoubleMatrix(1,1, mxREAL));
    mxSetField(plhs[3],0,fnames[1],mxCreateDoubleMatrix(1,1, mxREAL));
    mxSetField(plhs[3],0,fnames[2],mxCreateDoubleMatrix(1,1, mxREAL));
    mxSetField(plhs[3],0,fnames[3],mxCreateDoubleMatrix(1,1, mxREAL));
    mxSetField(plhs[3],0,fnames[4],mxCreateDoubleMatrix(1,1, mxREAL));
    mxSetField(plhs[3],0,fnames[5],mxCreateDoubleMatrix(1,1, mxREAL));
    mxSetField(plhs[3],0,fnames[6],mxCreateDoubleMatrix(1,1, mxREAL));
    mxSetField(plhs[3],0,fnames[7],mxCreateDoubleMatrix(1,1, mxREAL));
    mxSetField(plhs[3],0,fnames[8],mxCreateDoubleMatrix(1,1, mxREAL));
    mxSetField(plhs[3],0,fnames[9],mxCreateDoubleMatrix(1,1, mxREAL));
    mxSetField(plhs[3],0,fnames[10],mxCreateDoubleMatrix(1,1, mxREAL));
    iter = mxGetPr(mxGetField(plhs[3],0,fnames[0]));
    pdflag = mxGetPr(mxGetField(plhs[3],0,fnames[1]));   
    dreuse = mxGetPr(mxGetField(plhs[3],0,"reuse"));
    if(nlhs > 4)         
    	plhs[4] = mxCreateCellMatrix(ncones+(int)(nlincon>0)+(int)(nfix>0),1);        
    
    //Set Defaults
    maxtime = 1000;
    printLevel = 0;
    
    //Create DSDP Problem
    DSDP_ERR( DSDPCreate((int)ndec,&dsdp), "Error Creating DSDP Problem");
    //Set Monitor
    DSDP_ERR( DSDPSetMonitor(dsdp,DSDPMonitor,0), "Error Setting DSDP Monitor");
    
    //Set Dual Objective
    for (i=0;i<ndec;i++){
        DSDP_ERR( DSDPSetDualObjective(dsdp,(int)i+1,f[i]), "Error Adding Objective Coefficients"); }
    
    //Check finite bounds for allocation
    if(lb || ub)
        for(i=0;i<ndec;i++) {
            if(lb)
                if(!mxIsInf(lb[i]))
                    nLB++;
            if(ub)
                if(!mxIsInf(ub[i]))
                    nUB++;
        }
    
    //Set Bounds as BCone
    if(nLB || nUB) {
        DSDP_ERR( DSDPCreateBCone(dsdp, &bcone), "Error creating BCone");
        DSDP_ERR( BConeAllocateBounds(bcone, (int)(nLB+nUB)), "Error allocating bounds");        
        for(i=0;i<ndec;i++) {
            if(nLB > 0 && !mxIsInf(lb[i]))
                DSDP_ERR( BConeSetLowerBound(bcone, (int)i+1, lb[i]), "Error setting lower bound");
            if(nUB > 0 && !mxIsInf(ub[i]))
                DSDP_ERR( BConeSetUpperBound(bcone, (int)i+1, ub[i]), "Error setting upper bound");
        }
    }
    
    //Set Linear Inequality Constraints as LPCone
    if(nlincon) {
        int M = (int)mxGetM(pA);
        int N = (int)mxGetN(pA);
        DSDP_ERR( DSDPCreateLPCone(dsdp, &lpcone), "Error creating LPCone (inequalities)");
        //Create Memory to store A*x <= b in dsdp and integer format
        temp_jc = mxCalloc(N+2,sizeof(int));
        temp_ir = mxCalloc(lincon_nz+M,sizeof(int));
        temp_pr = mxCalloc(lincon_nz+M,sizeof(double));
        //Copy over linear A
        for(i=0;i<=(size_t)N;i++)
            temp_jc[i] = (int)A_jc[i];
        for(i=0;i<lincon_nz;i++) {
            temp_ir[i] = (int)A_ir[i];
            temp_pr[i] = A[i];
        }
        //Append linear rhs (b)
        temp_jc[N+1] = temp_jc[N] + M;
        for(i=lincon_nz,j=0;j<(size_t)M;j++) {
            if(b[j] != 0) {
                temp_ir[i] = (int)j;
                temp_pr[i++] = b[j];
            }
            else
                temp_jc[N+1]--;
        }
        #ifdef DEBUG
            mexPrintf("---- Inequality Constraints ----\n");
            for(i=0;i<=(size_t)(N+1);i++)
                mexPrintf("jc[%d] = %d\n",i,temp_jc[i]);
            for(i=0;i<lincon_nz+M;i++)
                mexPrintf("ir[%d] = %d, pr[%d] = %f\n",i,temp_ir[i],i,temp_pr[i]);
        #endif        
        //Set LP Cone Data
        DSDP_ERR( LPConeSetData2(lpcone, M, temp_jc, temp_ir, temp_pr), "Error setting LP Cone data (inequality)" );
        //Optionally set X data
        if(nlhs > 4) {
            mxSetCell(plhs[4],indcell,mxCreateDoubleMatrix(M,1,mxREAL));
            DSDP_ERR( LPConeSetXVec(lpcone,mxGetPr(mxGetCell(plhs[4],indcell++)),M), "Error setting LP Cone X data" );
        }
    }
    
    //Set Semidefinite Constraints as SDPCone
    if(ncones) {
        //Create the cone structure, specifying each constraint as a block
        DSDP_ERR( DSDPCreateSDPCone(dsdp,(int)ncones,&sdpcone), "Error creating SDPCone");
        //Add each constraint cone
        for(i=0;i<ncones;i++) {
            if(ncones == 1 && !mxIsCell(pSDP)) {
                if(nlhs > 4) {
                    mxSetCell(plhs[4],indcell,mxCreateDoubleMatrix(mxGetM(pSDP),1,mxREAL));
                    X = mxGetPr(mxGetCell(plhs[4],indcell++));
                }
                ndim = addSDPCone(sdpcone,pSDP,(int)i,X);
            }
            else {
                if(nlhs > 4) {
                    mxSetCell(plhs[4],indcell,mxCreateDoubleMatrix(mxGetM(mxGetCell(pSDP,i)),1,mxREAL));
                    X = mxGetPr(mxGetCell(plhs[4],indcell++));
                }
                ndim = addSDPCone(sdpcone,mxGetCell(pSDP,i),(int)i,X);
            }
            //Update max dim
            if(sdpnmax < ndim)
                sdpnmax = ndim;
        }
    }
    
    //Set y0
    if (y0)
        for (i=0;i<ndec;i++) {
            DSDP_ERR( DSDPSetY0(dsdp,(int)i+1,y0[i]), "Error setting Y0");            
        }
    
    //Determine whether to reuse schur complement matrix (dsdp authors' heuristic)
    if(ndec == 1)
        reuse = 1/sdpnmax;
    else
        reuse = ((int)ndec-2)/sdpnmax; 
    if (ndec<50 && reuse==0) reuse=1;
    if (reuse>=1) reuse++;
    reuse=reuse*reuse;
    if (ndec<2000 && ndec>10) reuse=10;
    if (ndec>12) reuse=12;    
    
    //Get DSDP Default Options
    DSDP_ERR( DSDPGetR(dsdp,&r0), "Error Getting R");
    DSDP_ERR( DSDPGetPenaltyParameter(dsdp,&penalty), "Error Getting Penalty Parameter");
    DSDP_ERR( DSDPGetPotentialParameter(dsdp,&rho), "Error Getting Potential Parameter");
    DSDP_ERR( DSDPGetDualBound(dsdp,&dbound), "Error Getting Dual Bound");
    DSDP_ERR( DSDPGetGapTolerance(dsdp,&gaptol), "Error Getting Gap Tolerance");
    DSDP_ERR( DSDPGetRTolerance(dsdp,&inftol), "Error Getting R Tolerance");
    DSDP_ERR( DSDPGetBarrierParameter(dsdp,&mu0), "Error Getting Barrier Parameter");
    DSDP_ERR( DSDPGetMaxTrustRadius(dsdp,&maxtrust), "Error Getting Max Trust Radius");
    DSDP_ERR( DSDPGetStepTolerance(dsdp,&steptol), "Error Getting Step Tolerance");
    DSDP_ERR( DSDPGetPTolerance(dsdp,&infptol), "Error Getting P Tolerance");
    DSDP_ERR( DSDPGetPNormTolerance(dsdp,&pnormtol), "Error Getting PNorm Tolerance");
    
    //Get Data Norms to establish y bounds
    DSDP_ERR( DSDPGetDataNorms(dsdp, datanorm), "Error Getting Data Norms");
    DSDP_ERR( DSDPGetYBounds(dsdp,&ylow,&yhigh), "Error Getting Y Bounds");
    if (datanorm[0]==0){DSDP_ERR( DSDPSetYBounds(dsdp,-1.0,1.0), "Error Setting Y Bounds");}
    
    //Get User Options (overwrites defaults above)
    if(nrhs > eOPTS && !mxIsEmpty(pOPTS)) {
        //OPTI Options
        GetIntegerOption(pOPTS,"maxiter",&maxiter);
        GetDoubleOption(pOPTS,"maxtime",&maxtime);
        GetIntegerOption(pOPTS,"display",&printLevel);
        //DSDP Options
        GetDoubleOption(pOPTS,"r0",&r0);
        GetDoubleOption(pOPTS,"penalty",&penalty);
        GetDoubleOption(pOPTS,"rho",&rho);
        GetDoubleOption(pOPTS,"dbound",&dbound);
        GetDoubleOption(pOPTS,"gaptol",&gaptol);
        GetDoubleOption(pOPTS,"rtol",&inftol);
        GetDoubleOption(pOPTS,"mu0",&mu0);
        GetDoubleOption(pOPTS,"maxtrust",&maxtrust);
        GetDoubleOption(pOPTS,"steptol",&steptol);
        GetDoubleOption(pOPTS,"ptol",&infptol);
        GetDoubleOption(pOPTS,"pnormtol",&pnormtol); 
        GetIntegerOption(pOPTS,"reuse",&reuse);
        GetIntegerOption(pOPTS,"rpos",&rpos);
        GetIntegerOption(pOPTS,"drho",&drho);
        //Check and set DSDP options without valid defaults
        if(mxGetField(pOPTS,0,"zbar") && !mxIsEmpty(mxGetField(pOPTS,0,"zbar"))) {
            GetDoubleOption(pOPTS,"zbar",&zbar);
            DSDP_ERR( DSDPSetZBar(dsdp,zbar), "Error Setting Z Bar");
        }
        if(mxGetField(pOPTS,0,"dlbound") && !mxIsEmpty(mxGetField(pOPTS,0,"dlbound"))) {
            GetDoubleOption(pOPTS,"dlbound",&dlbound);
            DSDP_ERR( DSDPSetDualLowerBound(dsdp,dlbound), "Error Setting Dual Lower Bound");
        }
        if(mxGetField(pOPTS,0,"ybound") && !mxIsEmpty(mxGetField(pOPTS,0,"ybound"))) {
            GetDoubleOption(pOPTS,"ybound",&yhigh); ylow = -yhigh;
            DSDP_ERR( DSDPSetYBounds(dsdp,ylow,yhigh), "Error Setting Y Bounds");
        }
    }

    //Set DSDP Options with Defaults
    DSDP_ERR( DSDPSetMaxIts(dsdp,maxiter), "Error Setting Max Iterations");    
    DSDP_ERR( DSDPSetR0(dsdp,r0), "Error Setting Option R0 ");        
    DSDP_ERR( DSDPSetPenaltyParameter(dsdp,penalty), "Error Setting Penalty Parameter");
    DSDP_ERR( DSDPSetPotentialParameter(dsdp,rho), "Error Setting Potential Parameter");
    DSDP_ERR( DSDPSetDualBound(dsdp,dbound), "Error Setting Dual Bound");
    DSDP_ERR( DSDPSetGapTolerance(dsdp,gaptol), "Error Setting Gap Tolerance");
    DSDP_ERR( DSDPSetRTolerance(dsdp,inftol), "Error Setting R Tolerance");
    DSDP_ERR( DSDPSetBarrierParameter(dsdp,mu0), "Error Setting Barrier Parameter");
	DSDP_ERR( DSDPSetMaxTrustRadius(dsdp,maxtrust), "Error Setting Max Trust Radius");
	DSDP_ERR( DSDPSetStepTolerance(dsdp,steptol), "Error Setting Step Tolerance")
    DSDP_ERR( DSDPSetPTolerance(dsdp,infptol), "Error Setting P Tolerance");
    DSDP_ERR( DSDPSetPNormTolerance(dsdp,pnormtol), "Error Setting PNorm Tolerance");   
    if(reuse < 0) reuse = 0; if(reuse > 15) reuse = 15;
    DSDP_ERR( DSDPReuseMatrix(dsdp,reuse), "Error Setting Reuse Matrix");    
    //Set Other DSDP Options
    DSDP_ERR( DSDPUsePenalty(dsdp,rpos), "Error Setting Use Penalty");
    DSDP_ERR( DSDPUseDynamicRho(dsdp,drho), "Error Setting Dynamic Rho");    
    if (lpb<0.1) lpb=0.1;
    if(lpcone) DSDP_ERR( LPConeScaleBarrier(lpcone,lpb), "Error Setting LPCone Scale Barrier");   
    
    //Set Fixed Variables
    if(fixed != NULL) {
        if(nlhs > 4) {            
            mxSetCell(plhs[4],indcell,mxCreateDoubleMatrix(nfix,1,mxREAL));
            X = mxGetPr(mxGetCell(plhs[4],indcell++));
        }
        else
            X = NULL;
        DSDP_ERR( DSDPSetFixedVariables(dsdp, fixed, &fixed[nfix], X, (int)nfix), "Error Setting Fixed Variables");
    }
    
    //Print Header
    if(printLevel) {
        mexPrintf("\n------------------------------------------------------------------\n");
        mexPrintf(" This is DSDP v%s\n",DSDP_VERSION); 
        mexPrintf(" Authors: Steve Benson, Yinyu Ye and Xiong Zhang\n\n");
        mexPrintf(" Problem Properties:\n");
        mexPrintf(" # Decision Variables:        %4d\n",ndec);
        mexPrintf(" # Linear Inequalities:       %4d ",nlincon);
        if(nlincon)
            mexPrintf("[%d nz]\n",lincon_nz);
        else
            mexPrintf("\n");        
        mexPrintf(" # Semidefinite Cones:        %4d\n",ncones);

        mexPrintf("------------------------------------------------------------------\n");
    }
    
    //Start timer
    start = clock();
    //Call DSDP Setup to initialize problem
    DSDP_ERR( DSDPSetup(dsdp), "Error setting up DSDP Problem, likely out of memory");
    //Now Solve the Problem
    status = DSDPSolve(dsdp);
    //Stop Timer
    end = clock();
    evaltime = ((double)(end-start))/CLOCKS_PER_SEC;
    //Determine Stop Reason
    if(status == 0) {
        DSDP_ERR( DSDPStopReason(dsdp,&reason), "Error retrieving post-solve stop reason"); }
    else if(status == DSDP_MAX_TIME || status == DSDP_USER_TERMINATION)
        reason = status;
    else {
        DSDP_ERR( status, "Error solving DSDP Problem!");}
    
    //Computer X and Get Solution Type
    if (reason!=DSDP_INFEASIBLE_START)
        DSDP_ERR( DSDPComputeX(dsdp), "Error computing post-solve x");
    DSDP_ERR( DSDPGetSolutionType(dsdp,&pdfeasible), "Error collecting post-solve solution type");
    
    //Copy Dual Solution
    DSDP_ERR( DSDPGetY(dsdp,x,(int)ndec), "Error returning Solution Vector");
    //Collect Output Statistics
    DSDPGetIts(dsdp,&iters);     
    DSDPGetDObjective(dsdp,dval);    
    DSDPGetPObjective(dsdp,pval);    
    DSDPGetR(dsdp,mxGetPr(mxGetField(plhs[3],0,"r")));
    DSDPGetBarrierParameter(dsdp,mxGetPr(mxGetField(plhs[3],0,"mu")));
    DSDPGetStepLengths(dsdp,mxGetPr(mxGetField(plhs[3],0,"pstep")),mxGetPr(mxGetField(plhs[3],0,"dstep")));
    DSDPGetPnorm(dsdp,mxGetPr(mxGetField(plhs[3],0,"pnorm")));
    DSDPGetYMaxNorm(dsdp,mxGetPr(mxGetField(plhs[3],0,"ynorm")));
    DSDPGetTraceX(dsdp,mxGetPr(mxGetField(plhs[3],0,"tracex")));
    DSDPGetPotentialParameter(dsdp,mxGetPr(mxGetField(plhs[3],0,"rho")));
    *dreuse = (double)reuse;
    
    //Assign to MATLAB
    *iter = (double)iters;    
    *exitflag = (double)reason;
    *pdflag = (double)pdfeasible;
    
    //Print Header
    if(printLevel){            
        //Detail termination reason
        switch(reason)
        {
            //Success
            case DSDP_CONVERGED:	
                mexPrintf("\n *** DSDP CONVERGED ***\n");  break;
            case DSDP_UPPERBOUND:
                mexPrintf("\n *** DSDP CONVERGED: Dual Objective exceeds its bound***\n"); break;
            //Error
            case DSDP_SMALL_STEPS:
                mexPrintf("\n *** TERMINATION: EARLY EXIT ***\n *** CAUSE: Terminated due to Small Steps ***\n"); break;
            case DSDP_MAX_IT:
                mexPrintf("\n *** TERMINATION: EARLY EXIT ***\n *** CAUSE: Maximum Iterations Reached ***\n"); break;
            case DSDP_MAX_TIME:
                mexPrintf("\n *** TERMINATION: EARLY EXIT ***\n *** CAUSE: Maximum Time Reached ***\n"); break;
            case DSDP_INFEASIBLE_START:
                mexPrintf("\n *** TERMINATION: EARLY EXIT ***\n *** CAUSE: Infeasible Starting Point ***\n"); break;
            case DSDP_USER_TERMINATION:
                mexPrintf("\n *** TERMINATION: EARLY EXIT ***\n *** CAUSE: User Exited ***\n"); break;            
            //Here is ok too?
            default:
                mexPrintf("\n *** DSDP FINISHED ***\n"); break;
        }
        //Detail solution status
        if(reason == DSDP_CONVERGED || reason == DSDP_UPPERBOUND) {
            switch(pdfeasible)
            {
                //Success
                case DSDP_PDFEASIBLE:
                    mexPrintf(" Solution Status: Both Primal and Dual are Feasible and Bounded\n"); break;             
                //Error
                case DSDP_UNBOUNDED:
                    mexPrintf(" Solution Status: Dual Unbounded, Primal Infeasible\n"); break;
                case DSDP_INFEASIBLE:
                    mexPrintf(" Solution Status: Primal Unbounded, Dual Infeasible\n"); break;
                case DSDP_PDUNKNOWN:
                default:
                    mexPrintf(" Solution Status: Unknown - Check Dual Bounds\n"); break;
            }
        }

        if(reason==DSDP_CONVERGED)
        	mexPrintf("\n Final Primal Objective:  %2.5g\n Final Dual Objective:    %2.5g\n In %5d iterations\n    %5.2f seconds\n",*pval,*dval,iters,evaltime);

        mexPrintf("------------------------------------------------------------------\n\n");
    }  

    //Free DSDP Problem
    DSDP_ERR( DSDPDestroy(dsdp), "Error Destroying DSDP Problem");
    //Free Temporary memory
    if(temp_jc)  {mxFree(temp_jc);  temp_jc  = NULL;}
    if(temp_ir)  {mxFree(temp_ir);  temp_ir  = NULL;}
    if(temp_pr)  {mxFree(temp_pr);  temp_pr  = NULL;}
}               
Esempio n. 4
0
void
mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
    MatlabCPPInitialize(false);

    // Check for proper number of arguments
    if ( (nrhs < NR_IN) || (nrhs > NR_IN + NR_IN_OPT) || \
            (nlhs < NR_OUT) || (nlhs > NR_OUT + NR_OUT_OPT) ) {
        mexErrMsgTxt("Wrong number of arguments.");
    }

    // fetch the input (we support matrices and cell arrays)
    std::vector< Eigen::VectorXd > theta_unary;
    std::vector< Eigen::VectorXd > theta_pair;

    if (!mxIsCell(THETA_UNARY_IN)) {
        GetMatlabPotentialFromMatrix(THETA_UNARY_IN, theta_unary);
        GetMatlabPotentialFromMatrix(THETA_PAIR_IN, theta_pair);
    }
    else {
        GetMatlabPotential(THETA_UNARY_IN, theta_unary);
        GetMatlabPotential(THETA_PAIR_IN, theta_pair);
    }
    
    Eigen::MatrixXi edges;
    GetMatlabMatrix(EDGES_IN, edges);

    double beta = mxGetScalar(BETA_IN);
    
    TreeInference inf = TreeInference(theta_unary, theta_pair, edges);
    inf.run(beta);
            
    LOGZ_OUT = mxCreateNumericMatrix(1, 1, mxDOUBLE_CLASS, mxREAL);
    double* logz_p = mxGetPr(LOGZ_OUT);
    logz_p[0] = inf.getLogPartitionSum();
    
    // return marginals (if input was provided as a matrix, also return
    // marginals in a matrix)
    if (nlhs > 1) {
        std::vector< Eigen::VectorXd >& mu_unary = inf.getUnaryMarginals();
        if (!mxIsCell(THETA_UNARY_IN)) {
            size_t num_states = mxGetM(THETA_UNARY_IN);
            size_t num_vars = mxGetN(THETA_UNARY_IN);
            MARGINALS_UNARY_OUT = mxCreateNumericMatrix(
                                    num_states, 
                                    num_vars,
                                    mxDOUBLE_CLASS, mxREAL);
            double* mu_res_p = mxGetPr(MARGINALS_UNARY_OUT);
            for (size_t v_idx=0; v_idx<mu_unary.size(); v_idx++) {
                for (size_t idx=0; idx<mu_unary[v_idx].size(); idx++) {
                    mu_res_p[v_idx*num_states+idx] = mu_unary[v_idx](idx);
                }
            }
        }
        else {
            mwSize dim_0 = static_cast<mwSize>(mu_unary.size());
            MARGINALS_UNARY_OUT = mxCreateCellArray(1, &dim_0);
            for (size_t v_idx=0; v_idx<mu_unary.size(); v_idx++) {
                mxArray* m = mxCreateNumericMatrix(
                                static_cast<int>(mu_unary[v_idx].size()),
                                1,
                                mxDOUBLE_CLASS, mxREAL);
                double* mu_res_p = mxGetPr(m);
                for (size_t idx=0; idx<mu_unary[v_idx].size(); idx++) {
                    mu_res_p[idx] = mu_unary[v_idx](idx);
                }

                mxSetCell(MARGINALS_UNARY_OUT, v_idx, m);
            }
        }
    }

    // return pairwise marginals
    if (nlhs > 2) {
        std::vector< Eigen::VectorXd >& mu_pair = inf.getPairwiseMarginals();
        if (!mxIsCell(THETA_UNARY_IN)) {
            size_t num_states = mxGetM(THETA_PAIR_IN);
            size_t num_edges = mxGetN(THETA_PAIR_IN);
            MARGINALS_PAIR_OUT = mxCreateNumericMatrix(
                                    num_states, 
                                    num_edges,
                                    mxDOUBLE_CLASS, mxREAL);
            double* mu_res_p = mxGetPr(MARGINALS_PAIR_OUT);
            for (size_t e_idx=0; e_idx<mu_pair.size(); e_idx++) {
                for (size_t idx=0; idx<mu_pair[e_idx].size(); idx++) {
                    mu_res_p[e_idx*num_states+idx] = mu_pair[e_idx](idx);
                }
            }
        }
        else {
            mxAssert(0, "not implemented yet!");
            // TODO: not implemented yet, see above!
            // see unary case above!
        }
    }

    MatlabCPPExit();
}
Esempio n. 5
0
/* [graphs, count] = mexgspan (G, minsup, maxpat);
 */
void
mexFunction (int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
{
	if (nlhs > 3) {
		mexPrintf ("Too many left hand side parameters.\n");
		return;
	}

	if (nrhs != 4 && nrhs != 10) {
		mexErrMsgTxt ("Wrong number of right hand side parameters (must be 4 or 10).\n");

		return;
	}

	if (mxIsCell (prhs[0]) == 0) {
		mexErrMsgTxt ("G must be a cellarray of graph structures.\n");

		return;
	}

	unsigned int minsup = (unsigned int) mxGetScalar (prhs[1]);
	if (mxGetM (prhs[2]) != 1 || mxGetN (prhs[2]) != 2) {
		mexErrMsgTxt ("size_req must be a (1,2) real vector.\n");

		return;
	}
	double* size_req = (double *) mxGetPr (prhs[2]);
	unsigned int maxpat_min = (unsigned int) size_req[0];
	unsigned int maxpat_max = (unsigned int) size_req[1];
	unsigned int directed = (unsigned int) mxGetScalar (prhs[3]);
	if (directed > 1) {
		mexErrMsgTxt ("Parameter 'directed' must be zero or 1.\n");
		return;
	}

	GSPAN::gSpan gspan;

	/* In case we should do graph boosting, we have to do some extra setup
	 * work, such as initializing the known labels of the graphs and their
	 * weights.
	 */
	if (nrhs == 10) {
		double boostTau = (double) mxGetScalar (prhs[6]);
		if (boostTau < 0.0) {
			mexErrMsgTxt ("Boost tau parameter must be >= 0.0.\n");
			return;
		}
		unsigned int boostN = (unsigned int) mxGetScalar (prhs[7]);

		double* boostYptr = (double *) mxGetPr (prhs[4]);
		double* boostWeightsPtr = (double *) mxGetPr (prhs[5]);
		unsigned int boostYlen = mxGetM (prhs[4]);
		std::vector<double> boostY;
		std::vector<double> boostWeights;
		for (unsigned int n = 0 ; n < boostYlen ; ++n) {
			boostY.push_back (boostYptr[n]);
			boostWeights.push_back (boostWeightsPtr[n]);
		}
		unsigned int boostMax = (unsigned int) mxGetScalar (prhs[8]);
		unsigned int boostType = (unsigned int) mxGetScalar (prhs[9]);

		gspan.boost_setup (boostN, boostTau, boostMax, boostY,
			boostWeights, boostType);
	}

	/* Start the actual gspan algorithm.  Before the graphs are converted from
	 * the Matlab structures to Taku's graph object format.
	 */
	gspan.run_graphs (prhs[0], nlhs, plhs,
		minsup, maxpat_min, maxpat_max,
		false, false, (directed == 1) ? true : false);
}
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
  if(nrhs < 3)
    mexErrMsgTxt("Minimum of three inputs required.");
  if (nlhs > 1)
    mexErrMsgTxt("Too many output arguments.");

  for (int i = 1 ; i < nrhs-2 ; ++i)
  {
    if (mxIsEmpty(prhs[i]) || (!mxIsChar(prhs[i]) && ((mxGetClassID(prhs[i]) != mxDOUBLE_CLASS) || mxIsComplex(prhs[i]) || (mxGetNumberOfElements(prhs[i]) != 1))))
      mexErrMsgTxt("Metadata's label or index must be set by a non-empty string or an integer respectively.");
  }
  if ((mxGetClassID(prhs[nrhs-2]) != mxDOUBLE_CLASS) || mxIsComplex(prhs[nrhs-2]) || (mxGetNumberOfElements(prhs[nrhs-2]) != 1))
    mexErrMsgTxt("The index for the metadata's value must be set by a single integer");
  bool invalidData = false;
  if (mxIsCell(prhs[nrhs-1]))
  {
    if (mxGetNumberOfElements(prhs[nrhs-1]) != 1)
      invalidData = true;
  }
  else if (mxIsChar(prhs[nrhs-1]))
  {
    if (mxGetM(prhs[nrhs-1]) != 1)
      invalidData = true;
  }
  else if ((mxGetClassID(prhs[nrhs-1]) != mxDOUBLE_CLASS) || mxIsComplex(prhs[nrhs-1]) || (mxGetNumberOfElements(prhs[nrhs-1]) != 1)) 
    invalidData = true;
  if (invalidData)
    mexErrMsgTxt("Unsupported metadata's value or the number of elements is greater than 1.");
  
  btk::Acquisition::Pointer acq = btk_MOH_get_object<btk::Acquisition>(prhs[0]);
  btk::MetaData::Iterator it;
  btk::MetaData::Pointer parent = btkMXExtractMetaDataIterator(&it, nrhs-3, prhs, acq->GetMetaData());
  
  if (!(*it)->HasInfo())
    mexErrMsgTxt("No metadata's info.");
  
  size_t index = static_cast<size_t>(mxGetScalar(prhs[nrhs-2])) - 1;
  if (index >= (*it)->GetInfo()->GetValues().size())
    mexErrMsgTxt("Invalid index to extract one metadata's value.");
    
  const mxArray* data = 0; 
  if (mxIsCell(prhs[nrhs-1]))
  {
    data = mxGetCell(prhs[nrhs-1], 0);
    if (!data || !mxIsChar(data))
      mexErrMsgTxt("Error in the value's format: only a string is accepted in cell.");
  }
  else
    data = prhs[nrhs-1];
  
  if (mxIsChar(data))
  {
    size_t strlen_ = (mxGetM(data) * mxGetN(data) * sizeof(mxChar)) + 1;
    char* d = (char*)mxMalloc(strlen_);
    mxGetString(data, d, strlen_);
    (*it)->GetInfo()->SetValue(static_cast<int>(index), d);
    mxFree(d);
  }
  else
    (*it)->GetInfo()->SetValue(static_cast<int>(index), mxGetScalar(data));
  
  if (nlhs > 0)
    plhs[0] = btkMXCreateMetaDataStructure(acq->GetMetaData());
};
Esempio n. 7
0
/* mexRays computes the following RAY features ; distance (ray1), orientation (ray3), norm (ray4)
 * @param name of the input image.
 * @param sigma specifies the standard deviation of the edge filter.
 * @param angle specifies the angle at which the features should be computed.
 * @param edge_low_threshold low threshold used for the canny edge detection.
 * @param edge_high_threshold high threshold used for the canny edge detection.
 */
void mexFunction(int nlhs,       mxArray *plhs[],
                 int nrhs, const mxArray *prhs[])
{
    mwSize nElements,j;
    mwSize number_of_dims;
    double start_angle;
    double end_angle;
    double step_angle;
    int strLength;
    mxArray    *tmp;
    char *pImageName;
    
    // Check for proper number of input and output arguments
    if ((nrhs != 4) && (nrhs != 6)) {
      mexErrMsgTxt("Four or six input arguments required.");
    } 
    if (nlhs > 1){
	mexErrMsgTxt("Too many output arguments.");
    }
    
    // Check data type of input argument
    if (!(mxIsCell(prhs[0]))) {
      mexErrMsgTxt("First input argument must be of type cell.");
    }
    if (!(mxIsDouble(prhs[1]))) {
      mexErrMsgTxt("Second input argument must be of type double.");
    }
    if (!(mxIsDouble(prhs[2]))) {
      mexErrMsgTxt("Third input argument must be of type double.");
    }
    if (!(mxIsDouble(prhs[3]))) {
      mexErrMsgTxt("Fourth input argument must be of type double.");
    }
    if ((nrhs > 4) && !(mxIsDouble(prhs[4]))) {
      mexErrMsgTxt("Fifth input argument must be of type double.");
    }
    if ((nrhs > 5) && !(mxIsDouble(prhs[5]))) {
      mexErrMsgTxt("Sixth input argument must be of type double.");
    }
    
    mexPrintf("Loading input parameters\n");
  
    // Get image name
    tmp = mxGetCell(prhs[0],0);
    strLength = mxGetN(tmp)+1;
    pImageName = (char*)mxCalloc(strLength, sizeof(char));
    mxGetString(tmp,pImageName,strLength);

    start_angle=*((double *)mxGetPr(prhs[1]));
    end_angle=*((double *)mxGetPr(prhs[2]));
    step_angle=*((double *)mxGetPr(prhs[3]));

    double low_th = 15000;
    double high_th = 30000;
    if(nrhs > 5)
      {
        low_th = *((double *)mxGetPr(prhs[4]));
        high_th = low_th + 10000;
        if(nrhs > 6)
          high_th = *((double *)mxGetPr(prhs[5]));
      }

    mexPrintf("computeRays\n");
    IplImage** rays2 = 0;
    computeDistanceDifferenceRays(pImageName,
                                  start_angle, end_angle, step_angle,
                                  rays2, 0, F_CANNY, true,
                                  low_th, high_th);
    
    /*
    int nAngles = (end_angle-start_angle)/step_angle;
    IplImage** rays1 = new IplImage*[nAngles];
    IplImage** rays3 = 0;
    IplImage** rays4 = 0;
    //IplImage** rays3 = new IplImage*[nAngles];
    //IplImage** rays4 = new IplImage*[nAngles];



    double angle = 0;
    for(int a = 0;a<nAngles;a++)
      {
        computeRays((const char*)pImageName, sigma, angle, &rays1[a],&rays3[a],&rays4[a],F_CANNY,true,low_th,high_th);
        angle =+ step_angle;
      }


    // Release images
    mexPrintf("Cleaning\n");
    for(int a = 0;a<nAngles;a++)
      {
        cvReleaseImage(&rays1);
        cvReleaseImage(&rays3);
        cvReleaseImage(&rays4);
      }
    */

    mxFree(pImageName);
}
Esempio n. 8
0
// Takes a MATLAB variable and writes in in Mathematica form to link
void toMma(const mxArray *var, MLINK link) {

    // the following may occur when retrieving empty struct fields
    // it showsup as [] in MATLAB so we return {}
    // note that non-existent variables are caught and handled in eng_get()
    if (var == NULL) {
        MLPutFunction(link, "List", 0);
        return;
    }

    // get size information
    mwSize depth = mxGetNumberOfDimensions(var);
    const mwSize *mbDims = mxGetDimensions(var);

    // handle zero-size arrays
    if (mxIsEmpty(var)) {
        if (mxIsChar(var))
            MLPutString(link, "");
        else
            MLPutFunction(link, "List", 0);
        return;
    }

    // translate dimension information to Mathematica order
    std::vector<int> mmDimsVec(depth);
    std::reverse_copy(mbDims, mbDims + depth, mmDimsVec.begin());
    int *mmDims = &mmDimsVec[0];

    int len = mxGetNumberOfElements(var);

    // numerical (sparse or dense)
    if (mxIsNumeric(var)) {
        mxClassID classid = mxGetClassID(var);

        // verify that var is of a supported class
        switch (classid) {
        case mxDOUBLE_CLASS:
        case mxSINGLE_CLASS:
        case mxINT32_CLASS:
        case mxINT16_CLASS:
        case mxUINT16_CLASS:
        case mxINT8_CLASS:
        case mxUINT8_CLASS:
            break;
        default:
            putUnknown(var, link);
            return;
        }

        if (mxIsSparse(var)) {
            // Note: I realised that sparse arrays can only hold double precision numerical types
            // in MATLAB R2013a.  I will leave the below implementation for single precision & integer
            // types in case future versions of MATLAB will add support for them.

            int ncols = mxGetN(var); // number of columns

            mwIndex *jc = mxGetJc(var);
            mwIndex *ir = mxGetIr(var);

            int nnz = jc[ncols]; // number of nonzeros

            MLPutFunction(link, CONTEXT "matSparseArray", 4);
            mlpPutIntegerList(link, jc, ncols + 1);
            mlpPutIntegerList(link, ir, nnz);

            // if complex, put as im*I + re
            if (mxIsComplex(var)) {
                MLPutFunction(link, "Plus", 2);
                MLPutFunction(link, "Times", 2);
                MLPutSymbol(link, "I");
                switch (classid) {
                 case mxDOUBLE_CLASS:
                    MLPutReal64List(link, mxGetPi(var), nnz); break;
                 case mxSINGLE_CLASS:
                    MLPutReal32List(link, (float *) mxGetImagData(var), nnz); break;
                 case mxINT16_CLASS:
                    MLPutInteger16List(link, (short *) mxGetImagData(var), nnz); break;
                 case mxINT32_CLASS:
                    MLPutInteger32List(link, (int *) mxGetImagData(var), nnz); break;
                 default:
                    assert(false); // should never reach here
                }
            }

            switch (classid) {
             case mxDOUBLE_CLASS:
                MLPutReal64List(link, mxGetPr(var), nnz); break;
             case mxSINGLE_CLASS:
                MLPutReal32List(link, (float *) mxGetData(var), nnz); break;
             case mxINT16_CLASS:
                MLPutInteger16List(link, (short *) mxGetData(var), nnz); break;
             case mxINT32_CLASS:
                MLPutInteger32List(link, (int *) mxGetData(var), nnz); break;
             default:
                assert(false); // should never reach here
            }

            MLPutInteger32List(link, mmDims, depth);
        }
        else // not sparse
        {
            MLPutFunction(link, CONTEXT "matArray", 2);

            // if complex, put as im*I + re
            if (mxIsComplex(var)) {
                MLPutFunction(link, "Plus", 2);
                MLPutFunction(link, "Times", 2);
                MLPutSymbol(link, "I");
                switch (classid) {
                 case mxDOUBLE_CLASS:
                    MLPutReal64Array(link, mxGetPi(var), mmDims, NULL, depth); break;
                 case mxSINGLE_CLASS:
                    MLPutReal32Array(link, (float *) mxGetImagData(var), mmDims, NULL, depth); break;
                 case mxINT32_CLASS:
                    MLPutInteger32Array(link, (int *) mxGetImagData(var), mmDims, NULL, depth); break;
                 case mxINT16_CLASS:
                    MLPutInteger16Array(link, (short *) mxGetImagData(var), mmDims, NULL, depth); break;
                 case mxUINT16_CLASS:
                  {
                    int *arr = new int[len];
                    unsigned short *mbData = (unsigned short *) mxGetImagData(var);
                    std::copy(mbData, mbData + len, arr);
                    MLPutInteger32Array(link, arr, mmDims, NULL, depth);
                    delete [] arr;
                    break;
                  }
                 case mxINT8_CLASS:
                  {
                    short *arr = new short[len];
                    char *mbData = (char *) mxGetImagData(var);
                    std::copy(mbData, mbData + len, arr);
                    MLPutInteger16Array(link, arr, mmDims, NULL, depth);
                    delete [] arr;
                    break;
                  }
                 case mxUINT8_CLASS:
                  {
                    short *arr = new short[len];
                    unsigned char *mbData = (unsigned char *) mxGetImagData(var);
                    std::copy(mbData, mbData + len, arr);
                    MLPutInteger16Array(link, arr, mmDims, NULL, depth);
                    delete [] arr;
                    break;
                  }
                 default:
                    assert(false); // should never reach here
                }
            }

            switch (classid) {
            case mxDOUBLE_CLASS:
                MLPutReal64Array(link, mxGetPr(var), mmDims, NULL, depth); break;
            case mxSINGLE_CLASS:
                MLPutReal32Array(link, (float *) mxGetData(var), mmDims, NULL, depth); break;
            case mxINT32_CLASS:
                MLPutInteger32Array(link, (int *) mxGetData(var), mmDims, NULL, depth); break;
            case mxINT16_CLASS:
                MLPutInteger16Array(link, (short *) mxGetData(var), mmDims, NULL, depth); break;
            case mxUINT16_CLASS:
             {
                int *arr = new int[len];
                unsigned short *mbData = (unsigned short *) mxGetData(var);
                std::copy(mbData, mbData + len, arr);
                MLPutInteger32Array(link, arr, mmDims, NULL, depth);
                delete [] arr;
                break;
             }
            case mxINT8_CLASS:
             {
                short *arr = new short[len];
                char *mbData = (char *) mxGetData(var);
                std::copy(mbData, mbData + len, arr);
                MLPutInteger16Array(link, arr, mmDims, NULL, depth);
                delete [] arr;
                break;
             }
            case mxUINT8_CLASS:
             {
                short *arr = new short[len];
                unsigned char *mbData = (unsigned char *) mxGetData(var);
                std::copy(mbData, mbData + len, arr);
                MLPutInteger16Array(link, arr, mmDims, NULL, depth);
                delete [] arr;
                break;
             }
            default:
                assert(false); // should never reach here
            }

            MLPutInteger32List(link, mmDims, depth);
        }
    }
    // logical (sparse or dense)
    else if (mxIsLogical(var))
        if (mxIsSparse(var)) {
            int ncols = mxGetN(var); // number of columns

            mwIndex *jc = mxGetJc(var);
            mwIndex *ir = mxGetIr(var);
            mxLogical *logicals = mxGetLogicals(var);

            int nnz = jc[ncols]; // number of nonzeros

            MLPutFunction(link, CONTEXT "matSparseLogical", 4);
            mlpPutIntegerList(link, jc, ncols + 1);
            mlpPutIntegerList(link, ir, nnz);

            short *integers = new short[nnz];
            std::copy(logicals, logicals+nnz, integers);

            MLPutInteger16List(link, integers, nnz);

            MLPutInteger32List(link, mmDims, depth);

            delete [] integers;
        }
        else // not sparse
        {
            mxLogical *logicals = mxGetLogicals(var);

            short *integers = new short[len];
            std::copy(logicals, logicals+len, integers);

            MLPutFunction(link, CONTEXT "matLogical", 2);
            MLPutInteger16Array(link, integers, mmDims, NULL, depth);
            MLPutInteger32List(link, mmDims, depth);

            delete [] integers;
        }
    // char array
    else if (mxIsChar(var)) {
        assert(sizeof(mxChar) == sizeof(unsigned short));
        // 1 by N char arrays (row vectors) are sent as a string
        if (depth == 2 && mbDims[0] == 1) {
            const mxChar *str = mxGetChars(var);
            MLPutFunction(link, CONTEXT "matString", 1);
            MLPutUTF16String(link, reinterpret_cast<const unsigned short *>(str), len); // cast may be required on other platforms: (mxChar *) str
        }
        // general char arrays are sent as an array of characters
        else {
            MLPutFunction(link, CONTEXT "matCharArray", 2);
            const mxChar *str = mxGetChars(var);
            MLPutFunction(link, "List", len);
            for (int i=0; i < len; ++i)
                MLPutUTF16String(link, reinterpret_cast<const unsigned short *>(str + i), 1);
            MLPutInteger32List(link, mmDims, depth);
        }
    }
    // struct
    else if (mxIsStruct(var)) {
        int nfields = mxGetNumberOfFields(var);
        MLPutFunction(link, CONTEXT "matStruct", 2);
        MLPutFunction(link, "List", len);
        for (int j=0; j < len; ++j) {
            MLPutFunction(link, "List", nfields);
            for (int i=0; i < nfields; ++i) {
                const char *fieldname;

                fieldname = mxGetFieldNameByNumber(var, i);
                MLPutFunction(link, "Rule", 2);
                MLPutString(link, fieldname);
                toMma(mxGetFieldByNumber(var, j, i), link);
            }
        }
        MLPutInteger32List(link, mmDims, depth);
    }
    // cell
    else if (mxIsCell(var)) {
        MLPutFunction(link, CONTEXT "matCell", 2);
        MLPutFunction(link, "List", len);
        for (int i=0; i < len; ++i)
            toMma(mxGetCell(var, i), link);
        MLPutInteger32List(link, mmDims, depth);
    }
    // unknown or failure; TODO distinguish between unknown and failure
    else
    {
        putUnknown(var, link);
    }
}
void mexFunction (int nlhs, mxArray *plhs[],
                  int nrhs, const mxArray *prhs[])
{

    mwSize n;
    float *b , *x;
    ldl_p chol;
    mwSize i;
    mwIndex *jld;
    s_hlevel *H;
    int nlevels;
    mxArray *C;


    /* Input validation */
    if (nrhs !=2)
        mexErrMsgTxt("Wrong number of input arguments");
    
    if (!mxIsCell(H_IN))
        mexErrMsgTxt("First argument must be a Hierarchy cell");

    if (!mxIsSingle(b_IN))   
      mexErrMsgTxt("Second argument must be a non-sparse single precision vector");

    if ( (mxGetN(b_IN)!=1)) 
        mexErrMsgTxt("Second argument must be a column vector");

    n = mxGetM(b_IN);
    nlevels = (int) MAX(mxGetM(H_IN),mxGetN(H_IN));
    H = malloc(nlevels*sizeof(s_hlevel));

	if (nlevels>1) {
		C = mxGetCell(H_IN,nlevels-2);
		H[nlevels-2].islast = (boolean) *(mxGetPr(mxGetField(C,0,"islast")));
        if (H[nlevels-2].islast)
			nlevels = nlevels-1; 
	}

  
    for (i=0; i<nlevels; i++) {
        
        C = mxGetCell(H_IN,i);
       
        H[i].islast = (boolean) *(mxGetPr(mxGetField(C,0,"islast")));
        H[i].iterative = (boolean) *(mxGetPr(mxGetField(C,0,"iterative")));
        
                
        if (i<(nlevels-1)) {
        H[i].cI = (mIndex *) mxGetPr(mxGetField(C,0,"cI"));
        H[i].nc =  (mSize) *(mxGetPr(mxGetField(C,0,"nc")));
        H[i].invD = (float *) mxGetPr(mxGetField(C,0,"invD"));
        H[i].dc = (boolean) *(mxGetPr(mxGetField(C,0,"dc")));
        H[i].repeat = (int) *(mxGetPr(mxGetField(C,0,"repeat")));
        H[i].lws1 = (float *) mxGetPr(mxGetField(C,0,"lws1"));
        H[i].lws2 = (float *) mxGetPr(mxGetField(C,0,"lws2"));
        H[i].sws1 = (float *) mxGetPr(mxGetField(C,0,"sws1"));
        H[i].sws2 = (float *) mxGetPr(mxGetField(C,0,"sws2"));
        H[i].sws3 = (float *) mxGetPr(mxGetField(C,0,"sws3"));
        }

        if (i==0)
        H[i].laplacian = (boolean) *(mxGetPr(mxGetField(C,0,"laplacian")));
        
        H[i].A.a = (float *) mxGetPr(mxGetField(mxGetField(C,0,"A"),0,"a"));
        H[i].A.ia = (mIndex *) mxGetPr(mxGetField(mxGetField(C,0,"A"),0,"ia"));
        H[i].A.ja = (mIndex *) mxGetPr(mxGetField(mxGetField(C,0,"A"),0,"ja"));  
        H[i].A.n = (mSize) *(mxGetPr(mxGetField(mxGetField(C,0,"A"),0,"n")));    
        H[i].A.issym = (boolean) *(mxGetPr(mxGetField(mxGetField(C,0,"A"),0,"issym")));    

                                                                    
        if (i==(nlevels-1)){
            
            if (!H[i].iterative){
                H[i].chol.ld.a = (double *) mxGetPr(mxGetField(mxGetField(mxGetField(C,0,"chol"),0,"ld"),0,"a"));
                H[i].chol.ld.ia = (mIndex *) mxGetPr(mxGetField(mxGetField(mxGetField(C,0,"chol"),0,"ld"),0,"ia"));        
                H[i].chol.ld.ja = (mIndex *) mxGetPr(mxGetField(mxGetField(mxGetField(C,0,"chol"),0,"ld"),0,"ja"));       
                H[i].chol.ld.n = (mSize ) *(mxGetPr(mxGetField(mxGetField(mxGetField(C,0,"chol"),0,"ld"),0,"n")));   
                
                H[i].chol.ldT.a = (double *) mxGetPr(mxGetField(mxGetField(mxGetField(C,0,"chol"),0,"ldT"),0,"a"));
                H[i].chol.ldT.ia = (mIndex *) mxGetPr(mxGetField(mxGetField(mxGetField(C,0,"chol"),0,"ldT"),0,"ia"));        
                H[i].chol.ldT.ja = (mIndex *) mxGetPr(mxGetField(mxGetField(mxGetField(C,0,"chol"),0,"ldT"),0,"ja"));       
                H[i].chol.ldT.n = (mSize ) *(mxGetPr(mxGetField(mxGetField(mxGetField(C,0,"chol"),0,"ldT"),0,"n"))); 
                
                H[i].chol.p   = (mIndex *) mxGetPr(mxGetField(mxGetField(C,0,"chol"),0,"p"));
                H[i].chol.invp   = (mIndex *) mxGetPr(mxGetField(mxGetField(C,0,"chol"),0,"invp"));
            }
            else {
                H[i].invD = (float *) mxGetPr(mxGetField(C,0,"invD"));
                H[i].lws1 = (float *) mxGetPr(mxGetField(C,0,"lws1"));
                H[i].lws2 = (float *) mxGetPr(mxGetField(C,0,"lws2"));
                H[i].sws1 = (float *) mxGetPr(mxGetField(C,0,"sws1"));
                H[i].sws2 = (float *) mxGetPr(mxGetField(C,0,"sws2"));
                H[i].sws3 = (float *) mxGetPr(mxGetField(C,0,"sws3"));
            }
        
        }


 
    }

    
    b = (float *) mxGetPr(b_IN);
    x_OUT = mxCreateNumericArray(1,&n,mxSINGLE_CLASS,mxREAL);
    x = (float *) mxGetPr(x_OUT);
    
    preconditioner( H, b, 0, 1,x);
    
    free(H);
    
    
    return;

}   
Esempio n. 10
0
File: py.cpp Progetto: invenia/matpy
static PyObject* mat2py(const mxArray *a) {
	size_t ndims = mxGetNumberOfDimensions(a);
	const mwSize *dims = mxGetDimensions(a);
	mxClassID cls = mxGetClassID(a);
	size_t nelem = mxGetNumberOfElements(a);
	char *data = (char*) mxGetData(a);
	char *imagData = (char*) mxGetImagData(a);

	if (debug) mexPrintf("cls = %d, nelem = %d, ndims = %d, dims[0] = %d, dims[1] = %d\n", cls, nelem, ndims, dims[0], dims[1]);

	if (cls == mxCHAR_CLASS) {
		char *str = mxArrayToString(a);
		PyObject *o = PyString_FromString(str);
		mxFree(str);
		return o;
	} else if (mxIsStruct(a)) {
		PyObject *o = PyDict_New();
		PyObject *list;
		PyObject *pyItem;
		mxArray *item;
		int i, j;
		const char *fieldName;

		int nfields = mxGetNumberOfFields(a);
		if (debug) mexPrintf("nfields = %d, nelem = %d\n", nfields, nelem);

		for(i = 0; i < nfields; i++) {
			fieldName = mxGetFieldNameByNumber(a, i);
			list = PyList_New(nelem);

			for(j = 0; j < nelem; j++) {
				item = mxGetFieldByNumber(a, j, i);
                if(item == NULL)
                {
                	Py_DECREF(list);
                	Py_DECREF(o);
                	mexErrMsgIdAndTxt("matpy:NullFieldValue", "Null field in struct");
                }
				pyItem = mat2py(item);
                if(pyItem == NULL)
                {
                	Py_DECREF(list);
                	Py_DECREF(o);
                    mexErrMsgIdAndTxt("matpy:UnsupportedVariableType", "Unsupported variable type in struct");
                }
    			
                PyList_SetItem(list, j, pyItem);
            }

            PyDict_SetItemString(o, fieldName, list);
		}

		Py_DECREF(list);

		return o;
	}

	PyObject *list = PyList_New(nelem);
	const char *dtype = NULL;
	if (mxIsCell(a)) 
	{
		dtype = "object";

		for (int i = 0; i < nelem; i++) 
		{
			PyObject *item = mat2py(mxGetCell(a, i));

			if(NULL != item)
			{
				PyList_SetItem(list, i, item);
			}
			else // Failure
			{
				Py_DECREF(list);
				mexErrMsgIdAndTxt("matpy:UnsupportedVariableType", "Unsupported variable type in a cell");
			}
		}
		return list;
	} else {
		if (imagData == NULL) {
#define CASE(cls,c_type,d_type,py_ctor) case cls: for (int i = 0; i < nelem; i++) { \
dtype=d_type; \
PyObject *item = py_ctor(*((c_type*) data)); \
if (debug) mexPrintf("Setting %d to %f (item = 0x%08X)\n", i, (double) *((c_type*) data), item); \
data += sizeof(c_type); \
if (PyList_SetItem(list, i, item) == -1) PyErr_Print(); } \
break
			switch(cls) {
			CASE(mxLOGICAL_CLASS, bool, "bool", PyBool_FromLong);
			CASE(mxDOUBLE_CLASS, double, "float64", PyFloat_FromDouble);
			CASE(mxSINGLE_CLASS, float, "float32", PyFloat_FromDouble);
			CASE(mxINT8_CLASS, char, "int8", PyInt_FromLong);
			CASE(mxUINT8_CLASS, unsigned char, "uint8", PyInt_FromLong);
			CASE(mxINT16_CLASS, short, "int16", PyInt_FromLong);
			CASE(mxUINT16_CLASS, unsigned short, "uint16", PyInt_FromLong);
			CASE(mxINT32_CLASS, int, "int32", PyInt_FromLong);
			CASE(mxUINT32_CLASS, unsigned int, "uint32", PyLong_FromLongLong);
			CASE(mxINT64_CLASS, long long, "int64", PyLong_FromLongLong);
			CASE(mxUINT64_CLASS, unsigned long long, "uint64", PyLong_FromUnsignedLongLong);
			default:
				mexErrMsgIdAndTxt("matpy:UnsupportedVariableType", "Unsupported variable type");
			}
		} else {
#undef CASE
#define CASE(cls,c_type,d_type) case cls: for (int i = 0; i < nelem; i++) { \
dtype = d_type; \
PyObject *item = PyComplex_FromDoubles(*((c_type*) data), *((c_type*) imagData)); \
data += sizeof(c_type); \
imagData += sizeof(c_type); \
PyList_SetItem(list, i, item); } \
break
			switch(cls) {
			CASE(mxDOUBLE_CLASS, double, "complex128");
			CASE(mxSINGLE_CLASS, float, "complex64");
			CASE(mxINT8_CLASS, char, "complex64");
			CASE(mxUINT8_CLASS, unsigned char, "complex64");
			CASE(mxINT16_CLASS, short, "complex64");
			CASE(mxUINT16_CLASS, unsigned short, "complex64");
			CASE(mxINT32_CLASS, int, "complex128");
			CASE(mxUINT32_CLASS, unsigned int, "complex128");
			CASE(mxINT64_CLASS, long long, "complex128");
			CASE(mxUINT64_CLASS, unsigned long long, "complex128");
			default:
				mexErrMsgIdAndTxt("matpy:UnsupportedVariableType", "Unsupported variable type");
			}
		}
	}
void
mexFunction (int nout, mxArray ** out, int nin, mxArray const ** in)
{
  SAMPLE sample;  /* training sample */
  LEARN_PARM learn_parm;
  KERNEL_PARM kernel_parm;
  STRUCT_LEARN_PARM struct_parm;
  STRUCTMODEL structmodel;
  int alg_type;

  enum {IN_ARGS=0, IN_SPARM} ;
  enum {OUT_W=0} ;

  /* SVM-light is not fully reentrant, so we need to run this patch first */
  init_qp_solver() ;
  verbosity = 0 ;
  kernel_cache_statistic = 0 ;

  if (nin != 2) {
    mexErrMsgTxt("Two arguments required") ;
  }

  /* Parse ARGS  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  char arg [1024 + 1] ;
  int argc ;
  char ** argv ;

  if (! uIsString(in[IN_ARGS], -1)) {
    mexErrMsgTxt("ARGS must be a string") ;
  }

  mxGetString(in[IN_ARGS], arg, sizeof(arg) / sizeof(char)) ;
  arg_split (arg, &argc, &argv) ;

  svm_struct_learn_api_init(argc+1, argv-1) ;

  read_input_parameters (argc+1,argv-1,
                         &verbosity, &struct_verbosity,
                         &struct_parm, &learn_parm,
                         &kernel_parm, &alg_type ) ;
  
  if (kernel_parm.kernel_type != LINEAR &&
      kernel_parm.kernel_type != CUSTOM) {
    mexErrMsgTxt ("Only LINEAR or CUSTOM kerneles are supported") ;
  }

  /* Parse SPARM ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  mxArray const * sparm_array = in [IN_SPARM] ;
  mxArray const * patterns_array ;
  mxArray const * labels_array ;
  mxArray const * kernelFn_array ;
  int numExamples, ei ;

  if (! sparm_array) {
    mexErrMsgTxt("SPARM must be a structure") ;
  }
  struct_parm.mex = sparm_array ;

  patterns_array = mxGetField(sparm_array, 0, "patterns") ;
  if (! patterns_array ||
      ! mxIsCell(patterns_array)) {
    mexErrMsgTxt("SPARM.PATTERNS must be a cell array") ;
  }

  numExamples = mxGetNumberOfElements(patterns_array) ;

  labels_array = mxGetField(sparm_array, 0, "labels") ;
  if (! labels_array ||
      ! mxIsCell(labels_array) ||
      ! mxGetNumberOfElements(labels_array) == numExamples) {
    mexErrMsgTxt("SPARM.LABELS must be a cell array "
                 "with the same number of elements of "
                 "SPARM.PATTERNS") ;
  }

  sample.n = numExamples ;
  sample.examples = (EXAMPLE *) my_malloc (sizeof(EXAMPLE) * numExamples) ;
  for (ei = 0 ; ei < numExamples ; ++ ei) {
    sample.examples[ei].x.mex = mxGetCell(patterns_array, ei) ;
    sample.examples[ei].y.mex = mxGetCell(labels_array,   ei) ;
    sample.examples[ei].y.isOwner = 0 ;
  }

  if (struct_verbosity >= 1) {
    mexPrintf("There are %d training examples\n", numExamples) ;
  }

  kernelFn_array = mxGetField(sparm_array, 0, "kernelFn") ;
  if (! kernelFn_array && kernel_parm.kernel_type == CUSTOM) {
    mexErrMsgTxt("SPARM.KERNELFN must be define for CUSTOM kernels") ;
  }
  if (kernelFn_array) {
    MexKernelInfo * info ;
    if (mxGetClassID(kernelFn_array) != mxFUNCTION_CLASS) {
      mexErrMsgTxt("SPARM.KERNELFN must be a valid function handle") ;
    }
    info = (MexKernelInfo*) kernel_parm.custom ;
    info -> structParm = sparm_array ;
    info -> kernelFn   = kernelFn_array ;
  }

  /* Learning  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  switch (alg_type) {
  case 0:
    svm_learn_struct(sample,&struct_parm,&learn_parm,&kernel_parm,&structmodel,NSLACK_ALG) ;
    break ;
  case 1:
    svm_learn_struct(sample,&struct_parm,&learn_parm,&kernel_parm,&structmodel,NSLACK_SHRINK_ALG);
    break ;
  case 2:
    svm_learn_struct_joint(sample,&struct_parm,&learn_parm,&kernel_parm,&structmodel,ONESLACK_PRIMAL_ALG);
    break ;
  case 3:
    svm_learn_struct_joint(sample,&struct_parm,&learn_parm,&kernel_parm,&structmodel,ONESLACK_DUAL_ALG);
    break ;
  case 4:
    svm_learn_struct_joint(sample,&struct_parm,&learn_parm,&kernel_parm,&structmodel,ONESLACK_DUAL_CACHE_ALG);
    break  ;
  case 9:
    svm_learn_struct_joint_custom(sample,&struct_parm,&learn_parm,&kernel_parm,&structmodel);
    break ;
  default:
    mexErrMsgTxt("Unknown algorithm type") ;
  }

  /* Write output  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */

  /* Warning: The model contains references to the original data 'docs'.
     If you want to free the original data, and only keep the model, you
     have to make a deep copy of 'model'. */

  mxArray * model_array = newMxArrayEncapsulatingSmodel (&structmodel) ;
  out[OUT_W] = mxDuplicateArray (model_array) ;
  destroyMxArrayEncapsulatingSmodel (model_array) ;
  
  free_struct_sample (sample) ;
  free_struct_model (structmodel) ;
  svm_struct_learn_api_exit () ;
  free_qp_solver () ;
}
Esempio n. 12
0
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { ALLOCATES();
  real     *X, XX[NN], Xk[NN], XXr[NN], D[N], DS[N], fD[N], V[NN], VS[NN], *O, Ok[NN];
  long     k1, K1, k2, K2, k3, K3, ii, jj;
  int      ORDER[N];
  char     STR[100];

  enum     symmetrize_ { NONE , X_Xt , Xt_X , PLUS };
  enum     symmetrize_ symmetrize;  
  
  enum     outs_types { ID , INVERSE , EIGVALS , EIGVECS , EIGVALSDIAG , MAXDIFF , SQRT , LOG , EXP , evalFUN , DET , TRACE };
  enum     outs_types outs[50];
  int      ndims, Odims[50];
  real     det;
  
  int      oid;
  int      D_computed, V_computed, D_sorted, V_sorted, ORDER_computed;
  int      dim1 , dim2;
  mxArray  *mxX;
  
  if( nlhs == 0 ){ nlhs = 1; }
  if( nlhs > nrhs-2 ){
    myErrMsgTxt("There are no enough inputs.\n");
  }

  if( mxIsCell( prhs[0] ) ){
    mxX = mxGetCell( prhs[0] , 0 );
    dim1 = myGetValue( mxGetCell( prhs[0] , 1 ) );
    dim2 = myGetValue( mxGetCell( prhs[0] , 2 ) );
  } else {
    mxX = prhs[0];
    dim1 = 1;
    dim2 = 2;
  }
  
  if( ( mySize( mxX , dim1-1 ) != N ) || ( mySize( mxX , dim1-1 ) != N ) ){
    myErrMsgTxt("size( X , %d ) and size( X , %d ) have to be equal to three.\n",dim1,dim2);
  }
  

  if( myIsEmpty( prhs[1] ) ){
    symmetrize = NONE;
  } else if( mxIsChar(prhs[1]) ){
    mxGetString( prhs[1], STR, 100 );
    
    if(        !myStrcmpi(STR,"+") ) {
      symmetrize = PLUS;
    } else if( !myStrcmpi(STR,"xt*x") || !myStrcmpi(STR,"xtx") ) {
      symmetrize = Xt_X;
    } else if( !myStrcmpi(STR,"x*xt") || !myStrcmpi(STR,"xxt") ) {
      symmetrize = X_Xt;
    } else {
      myErrMsgTxt("Second argument expected: 'xt*x' , 'x*xt' , '+' , or [].\n");
    }

  } else {
    myErrMsgTxt("Second argument expected: 'xt*x' , 'x*xt' , '+' , or [].\n");
  }
  

  for( oid = 0 ; oid < nlhs ; oid++ ){
    if( ! mxIsChar(prhs[oid+2]) ){
      myErrMsgTxt("Valids arguments are: 'id' 'eigval' 'eigvec' 'log' 'sqrt' 'exp' 'error'.\n");
    }
    mxGetString( prhs[oid+2], STR, 100 );
    
    if(        !myStrcmpi(STR,"id") ) {
      outs[oid] = ID;
    } else if( !myStrcmpi(STR,"inv") || !myStrcmpi(STR,"inverse") ) {
      outs[oid] = INVERSE;
    } else if( !myStrcmpi(STR,"det") ) {
      outs[oid] = DET;
    } else if( !myStrcmpi(STR,"trace") ) {
      outs[oid] = TRACE;
    } else if( !myStrcmpi(STR,"evec") || !myStrcmpi(STR,"v") || !myStrcmpi(STR,"eigenvec") || !myStrcmpi(STR,"eigvec") || !myStrcmpi(STR,"eigenvectors") ) {
      outs[oid] = EIGVECS;
    } else if( !myStrcmpi(STR,"eval") || !myStrcmpi(STR,"d") || !myStrcmpi(STR,"eigenval") || !myStrcmpi(STR,"eigval") || !myStrcmpi(STR,"eigenvalues") ) {
      outs[oid] = EIGVALS;
    } else if( !myStrcmpi(STR,"diag") || !myStrcmpi(STR,"dd") ) {
      outs[oid] = EIGVALSDIAG;
    } else if( !myStrcmpi(STR,"error") ) {
      outs[oid] = MAXDIFF;
    } else if( !myStrcmpi(STR,"sqrt") || !myStrcmpi(STR,"sqrtm") ) {
      outs[oid] = SQRT;
    } else if( !myStrcmpi(STR,"log") || !myStrcmpi(STR,"logm") ) {
      outs[oid] = LOG;
    } else if( !myStrcmpi(STR,"exp") || !myStrcmpi(STR,"expm") ) {
      outs[oid] = EXP;
    } else {
      myErrMsgTxt("Valids arguments are: 'id' 'inv' 'det' 'trace' 'eigval' 'eigvec' 'log' 'sqrt' 'exp' 'error'.\n");
    }
  }
  
  
  X = mxGetPr( mxX );
  ndims = myGetSizes( mxX , Odims );
  
  for( oid = 0 ; oid < nlhs ; oid++ ){
    switch( outs[oid] ){
      case ID:
        plhs[oid] = mxCreateNumericArray( ndims , Odims , mxREAL_CLASS , mxREAL );
        break;
      case INVERSE:
        plhs[oid] = mxCreateNumericArray( ndims , Odims , mxREAL_CLASS , mxREAL );
        break;
      case DET:
        Odims[dim1-1] = 1;
        Odims[dim2-1] = 1;
        plhs[oid] = mxCreateNumericArray( ndims , Odims , mxREAL_CLASS , mxREAL );        
        Odims[dim1-1] = N;
        Odims[dim2-1] = N;
        break;
      case TRACE:
        Odims[dim1-1] = 1;
        Odims[dim2-1] = 1;
        plhs[oid] = mxCreateNumericArray( ndims , Odims , mxREAL_CLASS , mxREAL );        
        Odims[dim1-1] = N;
        Odims[dim2-1] = N;
        break;
      case EIGVALS:
        Odims[dim2-1] = 1;
        plhs[oid] = mxCreateNumericArray( ndims , Odims , mxREAL_CLASS , mxREAL );
        Odims[dim2-1] = N;
        break;
      case EIGVECS:
        plhs[oid] = mxCreateNumericArray( ndims , Odims , mxREAL_CLASS , mxREAL );        
        break;
      case EIGVALSDIAG:
        plhs[oid] = mxCreateNumericArray( ndims , Odims , mxREAL_CLASS , mxREAL );        
        break;
      case MAXDIFF:
        Odims[dim1-1] = 1;
        Odims[dim2-1] = 1;
        plhs[oid] = mxCreateNumericArray( ndims , Odims , mxREAL_CLASS , mxREAL );        
        Odims[dim1-1] = N;
        Odims[dim2-1] = N;
        break;
      case EXP:
        plhs[oid] = mxCreateNumericArray( ndims , Odims , mxREAL_CLASS , mxREAL );        
        break;
      case LOG:
        plhs[oid] = mxCreateNumericArray( ndims , Odims , mxREAL_CLASS , mxREAL );        
        break;
      case SQRT:
        plhs[oid] = mxCreateNumericArray( ndims , Odims , mxREAL_CLASS , mxREAL );        
        break;
      case evalFUN:
        plhs[oid] = mxCreateNumericArray( ndims , Odims , mxREAL_CLASS , mxREAL );        
        break;
    }
  }
  
  K1 = 1;
  for( k1 = 0    ; k1 < dim1-1 ; k1++ ){  K1 *= Odims[k1]; }
  K2 = 1;
  for( k2 = dim1 ; k2 < dim2-1 ; k2++ ){  K2 *= Odims[k2]; }
  K3 = 1;
  for( k3 = dim2 ; k3 < ndims  ; k3++ ){  K3 *= Odims[k3]; }


  for( k3 = 0 ; k3 < K3 ; k3++ ){
  for( k2 = 0 ; k2 < K2 ; k2++ ){
  for( k1 = 0 ; k1 < K1 ; k1++ ){
    if( K1 == 1 && K2 == 1 ){
      memcpy( Xk , X + k3*NN , NN*sizeof( real ) );
    } else {
      for( jj = 0 ; jj < N ; jj++ ){ for( ii = 0 ; ii < N ; ii++ ){
        Xk[ ii + N*jj ] = X[  k1 + K1*( ii + N*( k2 + K2*( jj + N*k3 ))) ];
      } }
    }
    
    
    switch( symmetrize ){
      case NONE:
        memcpy( XX , Xk , NN*sizeof( real ) );
        break;

      case X_Xt:
        XX[0] = Xk[0]*Xk[0] + Xk[2]*Xk[2];
        XX[1] = Xk[1]*Xk[0] + Xk[3]*Xk[2];

        XX[2] = Xk[0]*Xk[1] + Xk[2]*Xk[3];
        XX[3] = Xk[1]*Xk[1] + Xk[3]*Xk[3];
        break;

      case Xt_X:
        XX[0] = Xk[0]*Xk[0] + Xk[1]*Xk[1];
        XX[1] = Xk[2]*Xk[0] + Xk[3]*Xk[1];

        XX[2] = Xk[0]*Xk[2] + Xk[1]*Xk[3];
        XX[3] = Xk[2]*Xk[2] + Xk[3]*Xk[3];
        break;

      case PLUS:
        XX[0]         = Xk[0];
        XX[1] = XX[2] = ( Xk[1] + Xk[2] )/2.0;
        XX[3]         = Xk[3];
        break;
    }
    
    D_computed      = 0;
    V_computed      = 0;
    ORDER_computed  = 0;
    D_sorted        = 0;
    V_sorted        = 0;
    
    for( oid = 0 ; oid < nlhs ; oid++ ){
      switch( outs[oid] ){
        case ID:
          memcpy( Ok , XX , NN*sizeof( real ) );
          
          O = mxGetPr( plhs[oid] );
          ToOutput2x2;
          break;
          
          
        case INVERSE:
          det = XX[0]*XX[3] - XX[1]*XX[2];
          det = 1.0/det;
          
          Ok[0] =  XX[3] *det;
          Ok[1] = -XX[1] *det;
          Ok[2] = -XX[2] *det;
          Ok[3] =  XX[0] *det;
          
          O = mxGetPr( plhs[oid] );
          ToOutput2x2;
          break;
          

        case DET:
          Ok[0] = XX[0]*XX[3] - XX[1]*XX[2];
          
          O = mxGetPr( plhs[oid] );
          ToOutput1x1;
          break;

          
        case TRACE:
          Ok[0] =  XX[0] + XX[3];
          
          O = mxGetPr( plhs[oid] );
          ToOutput1x1;
          break;

          
        case EIGVALS:
          if( !D_computed     ){ EigenValues2x2( XX , D );          D_computed = 1;      }
          if( !ORDER_computed ){ GetOrder( D, ORDER );              ORDER_computed = 1;  }
          if( !D_sorted       ){ SortEigenValues( D, ORDER , DS );  D_sorted = 1;        }
          
          memcpy( Ok , DS , N*sizeof( real ) );
          
          O = mxGetPr( plhs[oid] );
          ToOutput2x1;
          break;


        case EIGVALSDIAG:
          if( !D_computed     ){ EigenValues2x2( XX , D );          D_computed = 1;      }
          if( !ORDER_computed ){ GetOrder( D, ORDER );              ORDER_computed = 1;  }
          if( !D_sorted       ){ SortEigenValues( D, ORDER , DS );  D_sorted = 1;        }

          Ok[0] = DS[0];
          Ok[3] = DS[1];
          Ok[1] = Ok[2] = 0;

          O = mxGetPr( plhs[oid] );
          ToOutput2x2;
          break;

          
        case EIGVECS:
          if( !D_computed     ){ EigenValues2x2( XX , D );          D_computed = 1;      }
          if( !V_computed     ){ EigenVectors2x2( XX , D , V);      V_computed = 1;      }
          if( !ORDER_computed ){ GetOrder( D, ORDER );              ORDER_computed = 1;  }
          if( !V_sorted       ){ SortEigenVectors( V, ORDER , VS);  V_sorted = 1;        }

          memcpy( Ok , VS , NN*sizeof( real ) );
          
          O = mxGetPr( plhs[oid] );
          ToOutput2x2;
          break;


//         case MAXDIFF:
//           if( !D_computed     ){ EigenValuesSym3x3( XX , D );       D_computed = 1;      }
//           if( !V_computed     ){ EigenVectorsSym3x3( XX , D , V);   V_computed = 1;      }
// 
//           Ok[0] = V[0]*V[0]*D[0] + V[3]*V[3]*D[1] + V[6]*V[6]*D[2];
//           Ok[1] = V[1]*V[0]*D[0] + V[4]*V[3]*D[1] + V[7]*V[6]*D[2];
//           Ok[2] = V[2]*V[0]*D[0] + V[5]*V[3]*D[1] + V[8]*V[6]*D[2];
// 
//           Ok[3] = V[0]*V[1]*D[0] + V[3]*V[4]*D[1] + V[6]*V[7]*D[2];
//           Ok[4] = V[1]*V[1]*D[0] + V[4]*V[4]*D[1] + V[7]*V[7]*D[2];
//           Ok[5] = V[2]*V[1]*D[0] + V[5]*V[4]*D[1] + V[8]*V[7]*D[2];
// 
//           Ok[6] = V[0]*V[2]*D[0] + V[3]*V[5]*D[1] + V[6]*V[8]*D[2];
//           Ok[7] = V[1]*V[2]*D[0] + V[4]*V[5]*D[1] + V[7]*V[8]*D[2];
//           Ok[8] = V[2]*V[2]*D[0] + V[5]*V[5]*D[1] + V[8]*V[8]*D[2];
// 
//           Ok[0] =  MAX9( fabs( Ok[0] - XX[0] ) ,
//                          fabs( Ok[1] - XX[1] ) ,
//                          fabs( Ok[2] - XX[2] ) ,
//                          fabs( Ok[3] - XX[3] ) ,
//                          fabs( Ok[4] - XX[4] ) ,
//                          fabs( Ok[5] - XX[5] ) ,
//                          fabs( Ok[6] - XX[6] ) ,
//                          fabs( Ok[7] - XX[7] ) ,
//                          fabs( Ok[8] - XX[8] ) );
// 
//           O = mxGetPr( plhs[oid] );
//           ToOutput1x1;
//           break;
// 
//           
//         case SQRT:
//           if( !D_computed     ){ EigenValuesSym3x3( XX , D );       D_computed = 1;      }
//           if( !V_computed     ){ EigenVectorsSym3x3( XX , D , V);   V_computed = 1;      }
// 
//           fD[0] = sqrt( D[0] );
//           fD[1] = sqrt( D[1] );
//           fD[2] = sqrt( D[2] );
//           
//           FillOk;
//           O = mxGetPr( plhs[oid] );
//           ToOutput3x3;
//           break;
// 
//           
//         case LOG:
//           if( !D_computed     ){ EigenValuesSym3x3( XX , D );       D_computed = 1;      }
//           if( !V_computed     ){ EigenVectorsSym3x3( XX , D , V);   V_computed = 1;      }
// 
//           fD[0] = log( D[0] );
//           fD[1] = log( D[1] );
//           fD[2] = log( D[2] );
//           
//           FillOk;
//           O = mxGetPr( plhs[oid] );
//           ToOutput3x3;
//           break;

        #define r       eval[0]
        #define e       eval[1]
        #define er      eval[2]
        case EXP:
          r = XX[0] - XX[3];
          r = 4*XX[1]*XX[2] + r*r;
          
          if( r >= 0 ){
            r = sqrt(r);
            
            
            e = exp( ( XX[0] + XX[3] - r )/2 )/r/2.0;
            er = exp(r);
            
            Ok[0] = e * ( XX[3] - XX[0] + r + er*(XX[0]-XX[3]+r) );
            
            Ok[1] = e * XX[1] * ( er - 1 ) * 2;
            
            Ok[2] = e * XX[2] * ( er - 1 ) * 2;
            
            Ok[3] = e * ( XX[0] - XX[3] + r + er*(XX[3]-XX[0]+r) );

          } else {
            
            r = sqrt( -r );
            
            e = exp( ( XX[0] + XX[3] )/2 )/r;
            er = sin(r/2);
            
            Ok[0] = e * ( r*cos(r/2) + ( XX[0]-XX[3] )*er );
            
            Ok[1] = 2 * XX[1] * e * er;
            
            Ok[2] = 2 * XX[2] * e * er;            
            
            Ok[3] = e * ( r*cos(r/2) + ( XX[3]-XX[0] )*er );
            
          }
          
          
          O = mxGetPr( plhs[oid] );
          ToOutput2x2;
          break;

          
          
//         case evalFUN:
//           O = mxGetPr( plhs[oid] ) + k*NN;
//           if( !D_computed     ){ EigenValuesSym3x3( XX , D );       D_computed = 1;      }
//           if( !V_computed     ){ EigenVectorsSym3x3( XX , D , V);   V_computed = 1;      }
// 
//           fD[0] = exp( D[0] );
//           fD[1] = exp( D[1] );
//           fD[2] = exp( D[2] );
// 
//           mexCallMATLAB(int nlhs, mxArray *plhs[], int nrhs, mxArray *prhs[], const char *name)
//           
//           FillO
//           break;
      
      }
    }
    
  }}}
  
  EXIT: myFreeALLOCATES();
}
Esempio n. 13
0
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, CONSTmxArray *prhs[])
{
	static Boolean firstTime=1,deferAvailable;
	long priorityLevel=-1;
	double a;
	Stuff stuff;
	Boolean isString,oldMatlabBackgrounding;

	plhs;
	InitMEX();
	isString=nrhs>0 && (mxIsChar(prhs[0]) || mxIsCell(prhs[0]));
	if(nlhs>1 || nrhs<1 || nrhs>2 || (isString && nlhs>0))PrintfExit("Usage:\n\n%s",useRush);
	switch(nrhs){
	case 2:
		a=mxGetScalar(prhs[1]);
		if(a!=0 && a!=0.5 && a!=1 && a!=2 && a!=3 && a!=4 && a!=5 && a!=6 && a!=7)
			PrintfExit("Illegal priorityLevel %.1f. Must be 0, 0.5, 1, 2, 3, 4, 5, 6, or 7. Usage:\n%s",a,useRush);
		priorityLevel=a;
		if(a==0.5)priorityLevel=-1;
	case 1:
		if(!isString){
			// special case: get an array of timings
			double s,s0;
			long j;

			stuff.getTimes=mxGetScalar(prhs[0]);
			if(stuff.getTimes<1)
				PrintfExit("The first argument must be either a string (or strings) or a number.");
			plhs[0]=mxCreateDoubleMatrix(1,stuff.getTimes,mxREAL);
			if(plhs[0]==NULL)PrintfExit("Couldn't allocate %ld element array.",stuff.getTimes);
			stuff.mxTimes=plhs[0];
			stuff.iterations=10000;
			s=Seconds();
			s=Seconds();
			s0=Seconds()-s;
			s=Seconds();
			for(j=0;j<stuff.iterations;j++) ;
			s=Seconds()-s-s0;
			stuff.iterations=(0.001-s0)*stuff.iterations/s;
			// That many iterations plus a call to Seconds() should take 1 ms.
		}else stuff.getTimes=0;
		break;
	}
	if(1){
		// concatenate array or cell array of strings
		int error=0;
		mxArray *out,*in;

		in=(mxArray *)prhs[0];
		error=mexCallMATLAB(1,&out,1,&in,"CatStr"); // Psychtoolbox:PsychOneliners:CatStr.m
		stuff.mxString=out;
	}else{
		stuff.mxString=prhs[0];
	}
	stuff.trapErrors=1;
	stuff.error=0;
	
	#if TARGET_OS_MAC
		if(CanControlMatlabBackgrounding()){
			oldMatlabBackgrounding=MatlabBackgrounding(0);
		}else{
			if(firstTime){
				// Backgrounding is dangerous. Matlab would give time to another process while priority is raised.
				// Checking the enabled flag (on the disk) is slow, so we only do it once if backgrounding's off. But
				// if it's on, we give an error, and check again next time.
				if(IsMatlabBackgroundingEnabled()){
					PrintfExit("Rush: please turn off Matlab's \"Backgrounding\" Preference, in the File menu.\n");
				}else firstTime=0;
			}
		}
	#endif

	mexEvalString("lasterr('');");

	Rush(priorityLevel,&fun,&stuff);

	if(CanControlMatlabBackgrounding())MatlabBackgrounding(oldMatlabBackgrounding);
	if(stuff.error)mexErrMsgTxt("mexCallMATLAB error during Rush");	// never happens
	{
		// if there's a message in LASTERR, print it as an error, with a preface
		int nlhs=1,nrhs=0,error=0;
		mxArray *plhs[1]={NULL},*prhs[1]={NULL};
		char string[512]="Error during Rush: ",*errorMsg;

		errorMsg=string+strlen(string);
		error=mexCallMATLAB(nlhs,plhs,nrhs,prhs,"lasterr");
		error=mxGetString(plhs[0],errorMsg,sizeof(string)-strlen(string));
		if(strlen(errorMsg)>0)mexErrMsgTxt(string);
	}
}
Esempio n. 14
0
void mexFunction(int nlhs, mxArray *plhs[],
                 int nrhs, const mxArray *prhs[])
{
  const mxArray *srcmat;
  int ndim, *dimsize, eltsize;
  const int *dims;
  int ndimdest, *destdims, *destdimsize;
  char *src, *dest;
  int *rep;
  int i,nrep;
  int extra_rep = 1;
  int empty;

  if(nrhs < 2) mexErrMsgTxt("Usage: xrepmat(A, [N M ...])");
  srcmat = prhs[0];
  if(mxIsSparse(srcmat)) {
    mexErrMsgTxt("Sorry, can't handle sparse matrices yet.");
  }
  if(mxIsCell(srcmat)) {
    mexErrMsgTxt("Sorry, can't handle cell arrays yet.");
  }
  ndim = mxGetNumberOfDimensions(srcmat);
  dims = mxGetDimensions(srcmat);
  eltsize = mxGetElementSize(srcmat);

  /* compute dimension sizes */
  dimsize = mxCalloc(ndim, sizeof(int));
  dimsize[0] = eltsize*dims[0];
  for(i=1;i<ndim;i++) dimsize[i] = dimsize[i-1]*dims[i];

  /* determine repetition vector */
  ndimdest = ndim;
  if(nrhs == 2) {
    nrep = mxGetN(prhs[1]);
    if(nrep > ndimdest) ndimdest = nrep;
    rep = mxCalloc(ndimdest, sizeof(int));
    for(i=0;i<nrep;i++) {
      double repv = mxGetPr(prhs[1])[i];
      rep[i] = (int)repv;
    }
    if(nrep == 1) {
      /* special behavior */
      nrep = 2;
      rep[1] = rep[0];
    }
  }
  else {
    nrep = nrhs-1;
    if(nrep > ndimdest) ndimdest = nrep;
    rep = mxCalloc(ndimdest, sizeof(int));
    for(i=0;i<nrep;i++) {
      rep[i] = (int)*mxGetPr(prhs[i+1]);
    }
  }
  for(i=nrep;i<ndimdest;i++) rep[i] = 1;

  /* compute output size */
  destdims = mxCalloc(ndimdest, sizeof(int));
  for(i=0;i<ndim;i++) destdims[i] = dims[i]*rep[i];
  for(;i<ndimdest;i++) { 
    destdims[i] = rep[i];
    extra_rep *= rep[i];
  }
  destdimsize = mxCalloc(ndim, sizeof(int));
  destdimsize[0] = eltsize*destdims[0];
  for(i=1;i<ndim;i++) destdimsize[i] = destdimsize[i-1]*destdims[i];

    
  /* for speed, array should be uninitialized */
  plhs[0] = mxCreateNumericArray(ndimdest, destdims, mxGetClassID(srcmat), 
				  mxIsComplex(srcmat)?mxCOMPLEX:mxREAL);

  /* if any rep[i] == 0, output should be empty array.
     Added by KPM 11/13/02.
  */
  empty = 0;
  for (i=0; i < nrep; i++) {
    if (rep[i]==0) 
      empty = 1;
  }
  if (empty) 
    return;

  src = (char*)mxGetData(srcmat);
  dest = (char*)mxGetData(plhs[0]);
  repmat(dest,src,ndim,destdimsize,dimsize,dims,rep);
  if(ndimdest > ndim) memrep(dest,destdimsize[ndim-1],extra_rep);
  if(mxIsComplex(srcmat)) {
    src = (char*)mxGetPi(srcmat);
    dest = (char*)mxGetPi(plhs[0]);
    repmat(dest,src,ndim,destdimsize,dimsize,dims,rep);
    if(ndimdest > ndim) memrep(dest,destdimsize[ndim-1],extra_rep);
  }
}
void
mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
    MatlabCPPInitialize(false);

    // Check for proper number of arguments
    if ( (nrhs < NR_IN) || (nrhs > NR_IN + NR_IN_OPT) || \
            (nlhs < NR_OUT) || (nlhs > NR_OUT + NR_OUT_OPT) ) {
        mexErrMsgTxt("Wrong number of arguments.");
    }

    // fetch the input (we support matrices and cell arrays)
    std::vector< Eigen::VectorXd > theta_unary;
    std::vector< Eigen::VectorXd > theta_pair;

    if (!mxIsCell(THETA_UNARY_IN)) {
        GetMatlabPotentialFromMatrix(THETA_UNARY_IN, theta_unary);
        GetMatlabPotentialFromMatrix(THETA_PAIR_IN, theta_pair);
    }
    else {
        GetMatlabPotential(THETA_UNARY_IN, theta_unary);
        GetMatlabPotential(THETA_PAIR_IN, theta_pair);
    }
    
    Eigen::MatrixXi edges;
    GetMatlabMatrix(EDGES_IN, edges);

    // decomposition: cell array of edge index vectors
    std::vector< std::vector<size_t> > decomposition;
    size_t num = mxGetNumberOfElements(DECOMPOSITION_IN);
    decomposition.resize(num);
    for (size_t d_idx=0; d_idx<num; d_idx++) {
        const mxArray* v = mxGetCell(DECOMPOSITION_IN, d_idx);
        size_t num_edges = mxGetM(v);
        decomposition[d_idx].resize(num_edges);
	    const double* ptr = mxGetPr(v);
        for (size_t e_idx=0; e_idx<num_edges; e_idx++) {
            decomposition[d_idx][e_idx] = static_cast<size_t>(ptr[e_idx]);
        }
    }
    
    // parse options
    MexSmoothDDOptions options;
    if (nrhs >= 5) {
        bool opts_parsed = options.parse(OPTIONS_IN);
        if (!opts_parsed) {
            MatlabCPPExit();
            return;
        }
    }
    
    // set algorithm & parameters according to options
    SmoothDualDecomposition* sdd;
    /*if (options.solver == SOLVER_FISTADESCENT) {
        sdd = new SmoothDualDecompositionFistaDescent(theta_unary, theta_pair, edges, decomposition);
    }
    if (options.solver == SOLVER_FISTA) {
        sdd = new SmoothDualDecompositionFista(theta_unary, theta_pair, edges, decomposition);
    }
    else if (options.solver == SOLVER_GRADIENTDESCENT) {
        sdd = new SmoothDualDecompositionGradientDescent(theta_unary, theta_pair, edges, decomposition);
    }
    else if (options.solver == SOLVER_NESTEROV) {
        sdd = new SmoothDualDecompositionNesterov(theta_unary, theta_pair, edges, decomposition);
    }
    else {
        mxAssert(0, "Solver not found. Should not happen!");
    }*/
    // TODO
    sdd = new SmoothDualDecompositionFistaDescent(theta_unary, theta_pair, edges, decomposition);
    //sdd = new SmoothDualDecompositionLBFGS(theta_unary, theta_pair, edges, decomposition);
    sdd->setMaximumNumberOfIterations(options.num_max_iter);
    sdd->setEpsilonGradientNorm(options.eps_gnorm);

    // run the computations
    sdd->run(options.rho);

    // return marginals (if input was provided as a matrix, also return
    // marginals in a matrix)
    std::vector< Eigen::VectorXd >& mu_unary = sdd->getUnaryMarginals();
    if (!mxIsCell(THETA_UNARY_IN)) {
        size_t num_states = mxGetM(THETA_UNARY_IN);
        size_t num_vars = mxGetN(THETA_UNARY_IN);
        MARGINALS_UNARY_OUT = mxCreateNumericMatrix(
                                num_states, 
                                num_vars,
                                mxDOUBLE_CLASS, mxREAL);
        double* mu_res_p = mxGetPr(MARGINALS_UNARY_OUT);
        for (size_t v_idx=0; v_idx<mu_unary.size(); v_idx++) {
            for (size_t idx=0; idx<mu_unary[v_idx].size(); idx++) {
                mu_res_p[v_idx*num_states+idx] = mu_unary[v_idx](idx);
            }
        }
    }
    else {
        mwSize dim_0 = static_cast<mwSize>(mu_unary.size());
        MARGINALS_UNARY_OUT = mxCreateCellArray(1, &dim_0);
        for (size_t v_idx=0; v_idx<mu_unary.size(); v_idx++) {
            mxArray* m = mxCreateNumericMatrix(
                            static_cast<int>(mu_unary[v_idx].size()),
                            1,
                            mxDOUBLE_CLASS, mxREAL);
            double* mu_res_p = mxGetPr(m);
            for (size_t idx=0; idx<mu_unary[v_idx].size(); idx++) {
                mu_res_p[idx] = mu_unary[v_idx](idx);
            }

            mxSetCell(MARGINALS_UNARY_OUT, v_idx, m);
        }
    }

    // return history
    /*if (nlhs > 1) {
        std::vector<double> history_obj = lpqp.getHistoryObjective();
        std::vector<double> history_obj_qp = lpqp.getHistoryObjectiveQP();
        std::vector<double> history_obj_lp = lpqp.getHistoryObjectiveLP();
        std::vector<double> history_obj_decoded = lpqp.getHistoryObjectiveDecoded();
        std::vector<size_t> history_iteration = lpqp.getHistoryIteration();
        std::vector<double> history_beta = lpqp.getHistoryBeta();
        std::vector< Eigen::VectorXi > history_decoded = lpqp.getHistoryDecoded();

        const char *field_names[] = {"obj", "obj_qp", "obj_lp", "obj_decoded", "iteration", "beta", "decoded"};
        mwSize dims[2];
        dims[0] = 1;
        dims[1] = history_obj.size();
        HISTORY_OUT = mxCreateStructArray(2, dims, sizeof(field_names)/sizeof(*field_names), field_names);

        int field_obj, field_obj_qp, field_obj_lp, field_obj_decoded, field_iteration, field_beta, field_decoded;
        field_obj = mxGetFieldNumber(HISTORY_OUT, "obj");
        field_obj_qp = mxGetFieldNumber(HISTORY_OUT, "obj_qp");
        field_obj_lp = mxGetFieldNumber(HISTORY_OUT, "obj_lp");
        field_obj_decoded = mxGetFieldNumber(HISTORY_OUT, "obj_decoded");
        field_iteration = mxGetFieldNumber(HISTORY_OUT, "iteration");
        field_beta = mxGetFieldNumber(HISTORY_OUT, "beta");
        field_decoded = mxGetFieldNumber(HISTORY_OUT, "decoded");

        for (size_t i=0; i<history_obj.size(); i++) {
            mxArray *field_value;

            field_value = mxCreateDoubleMatrix(1,1,mxREAL);
            *mxGetPr(field_value) = history_obj[i];
            mxSetFieldByNumber(HISTORY_OUT, i, field_obj, field_value);
            
            field_value = mxCreateDoubleMatrix(1,1,mxREAL);
            *mxGetPr(field_value) = history_obj_qp[i];
            mxSetFieldByNumber(HISTORY_OUT, i, field_obj_qp, field_value);
            
            field_value = mxCreateDoubleMatrix(1,1,mxREAL);
            *mxGetPr(field_value) = history_obj_lp[i];
            mxSetFieldByNumber(HISTORY_OUT, i, field_obj_lp, field_value);
            
            field_value = mxCreateDoubleMatrix(1,1,mxREAL);
            *mxGetPr(field_value) = history_obj_decoded[i];
            mxSetFieldByNumber(HISTORY_OUT, i, field_obj_decoded, field_value);
            
            field_value = mxCreateDoubleMatrix(1,1,mxREAL);
            *mxGetPr(field_value) = static_cast<double>(history_iteration[i]);
            mxSetFieldByNumber(HISTORY_OUT, i, field_iteration, field_value);
            
            field_value = mxCreateDoubleMatrix(1,1,mxREAL);
            *mxGetPr(field_value) = history_beta[i];
            mxSetFieldByNumber(HISTORY_OUT, i, field_beta, field_value);
            
            if (options.with_decoded_history) {
                field_value = mxCreateDoubleMatrix(history_decoded[i].size(),1,mxREAL);
                double* decoded_res_p = mxGetPr(field_value);
                for (size_t idx=0; idx<history_decoded[i].size(); idx++) {
                    decoded_res_p[idx] = static_cast<double>(history_decoded[i][idx]);
                }
                mxSetFieldByNumber(HISTORY_OUT, i, field_decoded, field_value);
            }
        }
    }*/
    
    // return pairwise marginals
    if (nlhs > 1) {
        std::vector< Eigen::VectorXd >& mu_pair = sdd->getPairwiseMarginals();
        if (!mxIsCell(THETA_UNARY_IN)) {
            size_t num_states = mxGetM(THETA_PAIR_IN);
            size_t num_edges = mxGetN(THETA_PAIR_IN);
            MARGINALS_PAIR_OUT = mxCreateNumericMatrix(
                                    num_states, 
                                    num_edges,
                                    mxDOUBLE_CLASS, mxREAL);
            double* mu_res_p = mxGetPr(MARGINALS_PAIR_OUT);
            for (size_t e_idx=0; e_idx<mu_pair.size(); e_idx++) {
                for (size_t idx=0; idx<mu_pair[e_idx].size(); idx++) {
                    mu_res_p[e_idx*num_states+idx] = mu_pair[e_idx](idx);
                }
            }
        }
        else {
            mwSize dim_0 = static_cast<mwSize>(mu_pair.size());
            MARGINALS_PAIR_OUT = mxCreateCellArray(1, &dim_0);
            for (size_t e_idx=0; e_idx<mu_pair.size(); e_idx++) {
                mxArray* m = mxCreateNumericMatrix(
                                static_cast<int>(mu_pair[e_idx].size()),
                                1,
                                mxDOUBLE_CLASS, mxREAL);
                double* mu_res_p = mxGetPr(m);
                for (size_t idx=0; idx<mu_pair[e_idx].size(); idx++) {
                    mu_res_p[idx] = mu_pair[e_idx](idx);
                }

                mxSetCell(MARGINALS_PAIR_OUT, e_idx, m);
            }
        }
    }

    delete sdd;

    MatlabCPPExit();
}
Esempio n. 16
0
void mexFunction(	int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{   
    int i,j, k, status,buflen,Cnt, Hndl, L,M,N,  NumHandles, commandswitch;
    
    int *HndlArray;
    mxArray  *mymxArray;
    double *myDblPr;
    chtype RequestType;
    
    char PVName[PV_NAME_LENGTH_MAX+1];
    // char MCAMessageString[MCA_MESSAGE_STRING_LENGTH_MAX+1];
    
    
      

    dbr_string_t StrBuffer;
    
        
    
    const char *MCAInfoFields[]={"PVName","ElementCount","NativeType","State","MCAMessage","Host"};
    char *NativeTypeStrings[] = {"STRING","INT","FLOAT","ENUM","CHAR","LONG","DOUBLE"};
    


    
    if(!CA_INITIALIZED) // Initialize CA if not initialized (first call)
    {   mexPrintf("Initializing MATLAB Channel Access ... \n");
        status = ca_task_initialize();
        if(status!=ECA_NORMAL)
            mexErrMsgTxt("Unable to initialise Challel Access\n");
        CA_INITIALIZED = true;
        // Register a function to be called when a this mex-file is cleared from memory
        // with 'clear' or when exitting MATLAB
        mexAtExit(mca_cleanup);
        // Lock the mex-file so that it can not be cleared without explicitly
        // mexUnclock
        mexLock();
        
        //start periodic polling:
/*        PollTimerHandle = SetTimer(NULL,NULL,MCA_POLL_PERIOD,background_poll);
        if(PollTimerHandle)
            mexPrintf("Periodic CA polling started! System Timer ID: %u\n",PollTimerHandle);
        else
            mexWarnMsgTxt("Failed to start periodic CA polling\n");
 */       
        
    }

    commandswitch = (int)mxGetScalar(prhs[0]);
   
    switch(commandswitch)
    {  case 0: 
            mexUnlock();
            break;
    
        case 1: // MCAOPEN - add channel(s) by PV names, all arguments following prhs[0]
               // must be strings - names of PV's
            for(i=1;i<nrhs;i++)
            {   mxGetString(prhs[i],PVName,PV_NAME_LENGTH_MAX+1);
                status = ca_search(PVName,&(CHNLS[HandlesUsed].CHID));
                if(status == ECA_NORMAL) // if not - go on to the next PV name
                {   status = ca_pend_io(MCA_SEARCH_TIMEOUT);
                    if (status == ECA_NORMAL)
                    {   // Allocate persistent memory for the DataBuffer on this channel
                        // to hold all elements of the DBR_XXX type
                        // nearest to the native type
                        // RequestType = dbf_type_to_DBR(ca_field_type(CHNLS[HandlesUsed].CHID));
                        // Cnt=ca_element_count(CHNLS[HandlesUsed].CHID);
                        
                        
                        CHNLS[HandlesUsed].NumElements = ca_element_count(CHNLS[HandlesUsed].CHID);
                        CHNLS[HandlesUsed].NativeType2DBR = dbf_type_to_DBR(ca_field_type(CHNLS[HandlesUsed].CHID));
                        CHNLS[HandlesUsed].MonitorEventCount = 0;
                        
                        switch(CHNLS[HandlesUsed].NativeType2DBR)
                        {   case DBR_STRING:
                                CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_string_t));
                                
                            break;
                        
                            case DBR_INT: // As defined in db_access.h DBR_INT = DBR_SHORT = 1
                                CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_short_t)); 
                            break;
                        
                            case DBR_FLOAT:
                                CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_float_t)); 
                            break;
                
                            case DBR_ENUM:
                                CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_enum_t)); 
                            break;
                
                            case DBR_CHAR:
                                CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_char_t)); 
                            break;
                    
                            case DBR_LONG:
                                CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_short_t)); 
                            break;
                    
                            case DBR_DOUBLE:
                                CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_double_t)); 
                            break;
                        }   
                        mexMakeMemoryPersistent(CHNLS[HandlesUsed].DataBuffer);
                        
                                 
                        if(CHNLS[HandlesUsed].NativeType2DBR==DBR_STRING) // CACHE
                        {   if(CHNLS[HandlesUsed].NumElements==1) // Create MATLAB string - originally empty
                                CHNLS[HandlesUsed].CACHE = mxCreateString("");
                            else // Create MATLAB cell array of strings
                            {   CHNLS[HandlesUsed].CACHE = mxCreateCellMatrix(1,CHNLS[HandlesUsed].NumElements);
                                for(k=0;k<CHNLS[HandlesUsed].NumElements;k++)
                                {   mymxArray = mxCreateString("");
                                    mexMakeArrayPersistent(mymxArray);
                                    mxSetCell(CHNLS[HandlesUsed].CACHE, k, mymxArray);
                                }
                            }
                        }
                        else // Make CACHE a numeric mxArray 
                        {    CHNLS[HandlesUsed].CACHE = mxCreateDoubleMatrix(1,CHNLS[HandlesUsed].NumElements,mxREAL);  
                        }
                        
                        mexMakeArrayPersistent(CHNLS[HandlesUsed].CACHE);
                        
                        plhs[i-1]=mxCreateScalarDouble(++HandlesUsed);                        
                    
                    }
                    else
                        plhs[i-1]=mxCreateScalarDouble(0);

                }
                else
                    plhs[i-1]=mxCreateScalarDouble(0);
            } break;
            
        
        case 2:// MCAOPEN - add channel(s) by PV names. The arguments following prhs[0]
               // argument must be a cell array of strings - PV names
            
            L = mxGetM(prhs[1])*mxGetN(prhs[1]);
            plhs[0] = mxCreateDoubleMatrix(1,L,mxREAL);
            myDblPr = mxGetPr(plhs[0]);
            
            for(i=0;i<L;i++)
            {   mymxArray = mxGetCell(prhs[1],i);
                mxGetString(mymxArray,PVName,PV_NAME_LENGTH_MAX+1);
                status = ca_search(PVName,&(CHNLS[HandlesUsed].CHID));
                if(status == ECA_NORMAL) // if not - go on to the next PV name
                {   status = ca_pend_io(MCA_IO_TIMEOUT);
                    if (status == ECA_NORMAL)
                    {   // Allcate persistent memory for the DataBuffer on this channel
                        //RequestType = dbf_type_to_DBR(ca_field_type(CHNLS[HandlesUsed].CHID));
                        CHNLS[HandlesUsed].NativeType2DBR = dbf_type_to_DBR(ca_field_type(CHNLS[HandlesUsed].CHID));
                        CHNLS[HandlesUsed].NumElements = ca_element_count(CHNLS[HandlesUsed].CHID);
                        CHNLS[HandlesUsed].MonitorEventCount = 0;
                        //Cnt=ca_element_count(CHNLS[HandlesUsed].CHID);
                        switch(CHNLS[HandlesUsed].NativeType2DBR)
                        {   case DBR_STRING:
                                CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_string_t)); 
                            break;
                        
                            case DBR_INT: // As defined in db_access.h DBR_INT = DBR_SHORT = 1
                                CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_short_t)); 
                            break;
                        
                            case DBR_FLOAT:
                                CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_float_t)); 
                            break;
                
                        
                            case DBR_ENUM:
                                CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_enum_t)); 
                            break;
                
                            case DBR_CHAR:
                                CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_char_t)); 
                            break;
                    
                            case DBR_LONG:
                                CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_short_t)); 
                            break;
                    
                            case DBR_DOUBLE:
                                CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_double_t)); 
                            break;
                        }   
                        mexMakeMemoryPersistent(CHNLS[HandlesUsed].DataBuffer);   
                        
                        if(CHNLS[HandlesUsed].NativeType2DBR == DBR_STRING) // CACHE
                        {   CHNLS[HandlesUsed].CACHE = mxCreateCellMatrix(1,CHNLS[HandlesUsed].NumElements);
                            for(k=0;k<CHNLS[HandlesUsed].NumElements;k++)
                            {   mymxArray = mxCreateString(StrBuffer);
                                mexMakeArrayPersistent(mymxArray);
                                mxSetCell(CHNLS[HandlesUsed].CACHE, k, mymxArray);
                            }
                        }
                        else
                        {    CHNLS[HandlesUsed].CACHE = mxCreateDoubleMatrix(1,CHNLS[HandlesUsed].NumElements,mxREAL);  
                        }
                        
                        mexMakeArrayPersistent(CHNLS[HandlesUsed].CACHE);
                        
                        
                        myDblPr[i] = ++HandlesUsed;
                    }
                    else
                        myDblPr[i] = 0;
                }
                else
                    myDblPr[i] = 0;
            } break;
            
       case 3: // MCAOPEN Return names of connected channels as cell array of strings
            plhs[0] = mxCreateCellArray(1, &HandlesUsed);
            for(i=0;i<HandlesUsed;i++)
            {   if(CHNLS[i].CHID!=NULL)
                    {   mymxArray = mxCreateString(ca_name(CHNLS[i].CHID));
                        mxSetCell(plhs[0], i, mymxArray);
                    }
                else
                    {   mymxArray = mxCreateString("");
                        //mexPrintf("Handle: %d PV: %s\n",i+1, "Cleared Channel");
                        mxSetCell(plhs[0], i, mymxArray);
                    }
              } break;
        
        
         
        case 5: // MCACLOSE permanently clear channel
            Hndl = (int)mxGetScalar(prhs[1]);
            if(Hndl<1 || Hndl>HandlesUsed)
                mexErrMsgTxt("Handle out of range");  

            // If a monitor is installed, set the EVID pointer to NULL 
            // ca_clear_event dos not do it by itself

            if(CHNLS[Hndl-1].EVID) 
                CHNLS[Hndl-1].EVID = NULL;
                
            // If there is Callback String - destroy it
            if(CHNLS[Hndl-1].MonitorCBString)
            {   mxFree(CHNLS[Hndl-1].MonitorCBString); 
                CHNLS[Hndl-1].MonitorCBString =NULL;
            }    
            
            if(ca_state(CHNLS[Hndl-1].CHID)==3)
                mexWarnMsgTxt("Channel previously cleared");
            else
                if(ca_clear_channel(CHNLS[Hndl-1].CHID)!=ECA_NORMAL)
                    mexErrMsgTxt("ca_clear_channel failed");

            break;
            
        case 10: // MCAINFO return channels info as MATLAB structure array
            if(HandlesUsed>0)
            {   plhs[0] = mxCreateStructMatrix(1,HandlesUsed,6,MCAInfoFields);
                
                for(i=0;i<HandlesUsed;i++)
                {   mxSetFieldByNumber(plhs[0],i,0,mxCreateString(ca_name(CHNLS[i].CHID)));
                    mxSetFieldByNumber(plhs[0],i,1,mxCreateScalarDouble(ca_element_count(CHNLS[i].CHID)));
                    mxSetFieldByNumber(plhs[0],i,5,mxCreateString(ca_host_name(CHNLS[i].CHID)));
                    
                    switch(ca_state(CHNLS[i].CHID))
                    {   case 1: // Disconnected due to Server or Network - may reconnect 
                            mxSetFieldByNumber(plhs[0],i,2,mxCreateString("unknown"));
                            mxSetFieldByNumber(plhs[0],i,3,mxCreateString("disconnected"));
                            mxSetFieldByNumber(plhs[0],i,4,mxCreateString("Disconnected due to server or network problem"));
                            break;
                        case 2: // Normal connection
                            mxSetFieldByNumber(plhs[0],i,2,mxCreateString(NativeTypeStrings[ca_field_type(CHNLS[i].CHID)]));
                            mxSetFieldByNumber(plhs[0],i,3,mxCreateString("connected"));
                            mxSetFieldByNumber(plhs[0],i,4,mxCreateString("Normal connection"));
                            break;
                        case 3: // Disconnected by user
                            mxSetFieldByNumber(plhs[0],i,2,mxCreateString("unknown"));
                            mxSetFieldByNumber(plhs[0],i,3,mxCreateString("disconnected"));
                            mxSetFieldByNumber(plhs[0],i,4,mxCreateString("Permanently disconnected (cleared) by the user"));                    
                            break;
                    }    
                }
            }
            else
            {   mexWarnMsgTxt("No connected PV's found"); 
                plhs[0] = mxCreateDoubleMatrix(0,0,mxREAL);
                
            }
            break;    
        
            
        case 11: // MCAINFO return info for 1 channel by handle number 
            Hndl = (int)mxGetScalar(prhs[1]);
            if(Hndl<1 || Hndl>HandlesUsed)
                mexErrMsgTxt("Handle out of range");  
                
            plhs[0] = mxCreateStructMatrix(1,1,6,MCAInfoFields);

            mxSetFieldByNumber(plhs[0],0,0,mxCreateString(ca_name(CHNLS[Hndl-1].CHID)));
            mxSetFieldByNumber(plhs[0],0,1,mxCreateScalarDouble(ca_element_count(CHNLS[Hndl-1].CHID)));
            mxSetFieldByNumber(plhs[0],0,5,mxCreateString(ca_host_name(CHNLS[Hndl-1].CHID)));
            
            switch(ca_state(CHNLS[Hndl-1].CHID))
            {  case 1: // Disconnected due to Server or Network - may reconnect 
                    mxSetFieldByNumber(plhs[0],0,2,mxCreateString("unknown"));
                    mxSetFieldByNumber(plhs[0],0,3,mxCreateString("disconnected"));
                    mxSetFieldByNumber(plhs[0],0,4,mxCreateString("Disconnected due to server or network problem"));
                    break;
                case 2: // Normal connection
                    mxSetFieldByNumber(plhs[0],0,2,mxCreateString(NativeTypeStrings[ca_field_type(CHNLS[Hndl-1].CHID)]));
                    mxSetFieldByNumber(plhs[0],0,3,mxCreateString("connected"));
                    mxSetFieldByNumber(plhs[0],0,4,mxCreateString("Normal connection"));
                    break;
                case 3: // Disconnected by user
                    mxSetFieldByNumber(plhs[0],0,2,mxCreateString("unknown"));
                    mxSetFieldByNumber(plhs[0],0,3,mxCreateString("disconnected"));
                    mxSetFieldByNumber(plhs[0],0,4,mxCreateString("Permanently disconnected (cleared) by the user"));                    
                    break;
            };    
            
        break;    
        
        case 12: // MCASTATE return an array of status (1 - OK, 0 - disconnected or cleared) 
            if(HandlesUsed>0)
            {   plhs[0] = mxCreateDoubleMatrix(1,HandlesUsed,mxREAL);
                myDblPr = mxGetPr(plhs[0]);
                for(i=0;i<HandlesUsed;i++)
                    myDblPr[i] = (double)(ca_state(CHNLS[i].CHID)==2);
            }
            else
            {   mexWarnMsgTxt("No connected PV's found"); 
                plhs[0] = mxCreateDoubleMatrix(0,0,mxREAL);
                
            }
            break;    
        
        
        case 30: // poll
            ca_poll();
        break;
            

        case 50: // MCAGET Get PV values by their MCA handles
            
            for(i=0;i<nrhs-1;i++) // First loop: place all ca_get requests in the buffer
            {   Hndl = (int)mxGetScalar(prhs[1+i]); //start from[1]:  [0] argument is the commnads switch
                if(Hndl<1 || Hndl>HandlesUsed)
                    mexErrMsgTxt("Invalid Handle");
                
                RequestType = dbf_type_to_DBR(ca_field_type(CHNLS[Hndl-1].CHID));
                Cnt = ca_element_count(CHNLS[Hndl-1].CHID);
                status = ca_array_get(RequestType,Cnt,CHNLS[Hndl-1].CHID,CHNLS[Hndl-1].DataBuffer);
                if(status!=ECA_NORMAL)
                    mexPrintf("Error in call to ca_array_get\n");
            }   
            
            status = ca_pend_io(MCA_GET_TIMEOUT);
            if(status!=ECA_NORMAL)
                mexErrMsgTxt("... ca_pend_io call timed out \n");
            
            
            for(i=0;i<nrhs-1;i++) // Another loop to copy data from temp structures to MATLAB
            
            {   Hndl = (int)mxGetScalar(prhs[1+i]);
                RequestType = RequestType = dbf_type_to_DBR(ca_field_type(CHNLS[Hndl-1].CHID));
                Cnt = ca_element_count(CHNLS[Hndl-1].CHID);
                
                if(RequestType==DBR_STRING)
                {   if(Cnt==1)
                        plhs[i] = mxCreateString((char*)(*((dbr_string_t*)(CHNLS[Hndl-1].DataBuffer))));
                    else
                    {   plhs[i] = mxCreateCellMatrix(1,Cnt);
                        for(j=0;j<Cnt;j++)
                            mxSetCell(plhs[i], j, mxCreateString((char*)(*((dbr_string_t*)(CHNLS[Hndl-1].DataBuffer)+j))));
                    }
                }
                
                else 
                {   plhs[i] = mxCreateDoubleMatrix(1,Cnt,mxREAL);
                    myDblPr = mxGetPr(plhs[i]);
                                        
                    switch(dbf_type_to_DBR(ca_field_type(CHNLS[Hndl-1].CHID)))
                    
                    {   case DBR_INT: // As defined in db_access.h DBR_INT = DBR_SHORT = 1
                        for(j=0;j<Cnt;j++)
                            myDblPr[j]= (double)(*((dbr_short_t*)(CHNLS[Hndl-1].DataBuffer)+j));
                        break;    
                 
                        case DBR_FLOAT:
                        for(j=0;j<Cnt;j++)
                            myDblPr[j]= (double)(*((dbr_float_t*)(CHNLS[Hndl-1].DataBuffer)+j));
                        break;
                
                        case DBR_ENUM:
                        for(j=0;j<Cnt;j++)
                            myDblPr[j]= (double)(*((dbr_enum_t*)(CHNLS[Hndl-1].DataBuffer)+j));
                        break;
                
                        case DBR_CHAR:
                        for(j=0;j<Cnt;j++)
                            myDblPr[j]= (double)(*((dbr_char_t*)(CHNLS[Hndl-1].DataBuffer)+j));
                        break;
                    
                        case DBR_LONG:
                        for(j=0;j<Cnt;j++)
                            myDblPr[j]= (double)(*((dbr_long_t*)(CHNLS[Hndl-1].DataBuffer)+j));
                        break;
                    
                        case DBR_DOUBLE:
                        for(j=0;j<Cnt;j++)
                            myDblPr[j]= (double)(*((dbr_double_t*)(CHNLS[Hndl-1].DataBuffer)+j));
                        break;
                    } 

                }
                
            } break;            

            case 51: // MCAGET Get scalar PV of the same type 
                     // second argument is an array of handles
                     // returns an array of values
            
            myDblPr = mxGetPr(prhs[1]);
            M = mxGetM(prhs[1]);
            N = mxGetN(prhs[1]);
            
            NumHandles = M*N;
            plhs[0] = mxCreateDoubleMatrix(M,N,mxREAL);
            
            for(i=0;i<NumHandles;i++) // First loop: place all ca_get requests in the buffer
            {   Hndl = (int)myDblPr[i];
                if(Hndl<1 || Hndl>HandlesUsed)
                    mexErrMsgTxt("Invalid Handle");
                
                RequestType = dbf_type_to_DBR(ca_field_type(CHNLS[Hndl-1].CHID));
                status = ca_array_get(DBR_DOUBLE,1,CHNLS[Hndl-1].CHID,mxGetPr(plhs[0])+i);
                if(status!=ECA_NORMAL)
                    mexPrintf("Error in call to ca_array_get\n");
            }   
            
            status = ca_pend_io(MCA_GET_TIMEOUT);
            if(status!=ECA_NORMAL)
                mexErrMsgTxt("... ca_pend_io call timed out \n");
            
            break;            

        
       
        case 70: // MCAPUT
            NumHandles = (nrhs-1)/2;
            for(i=0;i<NumHandles;i++)
            {   j = 2+i*2;
                Hndl = (int)mxGetScalar(prhs[1+i*2]); 
                if(Hndl<1 || Hndl>HandlesUsed)
                    mexErrMsgTxt("Handle out of range - no values written");
                // Set the status to 0 - mcaput_callback will write 1, if successful
                CHNLS[Hndl-1].LastPutStatus = 0;    
                RequestType = dbf_type_to_DBR(ca_field_type(CHNLS[Hndl-1].CHID));            
                Cnt = ca_element_count(CHNLS[Hndl-1].CHID);
                
                
                // If a value to write is passed as a string - the number of elements to write 
                //   is 1 , NOT the length of the string returned by mxGetNumberOfElements
                if(mxIsChar(prhs[j])) 
                    L=1;
                else
                    L = min(mxGetNumberOfElements(prhs[j]),Cnt);
                

                // Copy double or string data from MATLAB prhs[] to DataBuffer
                // on each channel 
                
                if(RequestType==DBR_STRING)
                {   // STRING type is is passed as a cell array of strings
                    // A a 1-row MATLAB character array (1 string) may also be passed as a value
                    
                    if(mxIsChar(prhs[j]))
                    {   mxGetString(prhs[j], StrBuffer, sizeof(dbr_string_t));
                        strcpy((char*)(*((dbr_string_t*)(CHNLS[Hndl-1].DataBuffer))),StrBuffer);
                        
                    }
                    else if(mxIsCell(prhs[j]))
                    {   for(k=0;k<L;k++)
                        {   mxGetString(mxGetCell(prhs[j],k), StrBuffer, sizeof(dbr_string_t));
                            strcpy((char*)(*((dbr_string_t*)(CHNLS[Hndl-1].DataBuffer)+k)),StrBuffer);
                        }
                    }
                }
                else
                {   myDblPr = mxGetPr(prhs[j]); 
                    switch(RequestType)
                    {   
                        case DBR_INT: // As defined in db_access.h DBR_INT = DBR_SHORT = 1
                        for(k=0;k<L;k++)
                            *((dbr_short_t*)(CHNLS[Hndl-1].DataBuffer)+k) = (dbr_short_t)(myDblPr[k]);
                        break;    
                 
                        case DBR_FLOAT:
                        for(k=0;k<L;k++)
                            *((dbr_float_t*)(CHNLS[Hndl-1].DataBuffer)+k) = (dbr_float_t)(myDblPr[k]);
                        break;
                
                        case DBR_ENUM:
                        for(k=0;k<L;k++)
                            *((dbr_enum_t*)(CHNLS[Hndl-1].DataBuffer)+k) = (dbr_enum_t)(myDblPr[k]);
                        break;
                
                        case DBR_CHAR:
                        for(k=0;k<L;k++)
                            *((dbr_char_t*)(CHNLS[Hndl-1].DataBuffer)+k) = (dbr_char_t)(myDblPr[k]);
                        break;
                   
                        case DBR_LONG:
                        for(k=0;k<L;k++)
                            *((dbr_long_t*)(CHNLS[Hndl-1].DataBuffer)+k) = (dbr_long_t)(myDblPr[k]);
                        break;
                    
                        case DBR_DOUBLE:
                        for(k=0;k<L;k++)
                            *((dbr_double_t*)(CHNLS[Hndl-1].DataBuffer)+k) = (dbr_double_t)(myDblPr[k]);
                        break;
                    } 
                }            
 
                // place request in the que 
                status = ca_array_put_callback(RequestType,L,CHNLS[Hndl-1].CHID,CHNLS[Hndl-1].DataBuffer,
                                                   mcaput_callback,&(CHNLS[Hndl-1].LastPutStatus));

                 if(status!=ECA_NORMAL)
                    mexPrintf("ca_array_put_callback failed\n");
            }   
            
            status = ca_pend_event(MCA_PUT_TIMEOUT);
            
            plhs[0]=mxCreateDoubleMatrix(1,NumHandles,mxREAL);
            myDblPr = mxGetPr(plhs[0]);  
            
            for(i=0;i<NumHandles;i++)
            {   Hndl = (int)mxGetScalar(prhs[1+i*2]);
                myDblPr[i] = (double)CHNLS[Hndl-1].LastPutStatus;
                
            }
           
            break;
        
       case 80: // MCAPUT - fast unconfirmed put for scalar numeric PV's
        
            myDblPr = mxGetPr(prhs[1]);
            M = mxGetM(prhs[1]);
            N = mxGetN(prhs[1]);                
            NumHandles = M*N;
            
            plhs[0] = mxCreateDoubleMatrix(M,N,mxREAL);
            myDblPr = mxGetPr(plhs[0]);  
            
            for(i=0;i<NumHandles;i++)
            {   myDblPr = mxGetPr(plhs[0]);
                Hndl = (int)(*(mxGetPr(prhs[1])+i)); 
                if(Hndl<1 || Hndl>HandlesUsed)
                    mexErrMsgTxt("Handle out of range - no values written");

                status = ca_array_put(DBR_DOUBLE,1,CHNLS[Hndl-1].CHID,mxGetPr(prhs[2])+i);

                if(status!=ECA_NORMAL)
                    {   myDblPr[i] = 0;
                        //mexPrintf("ca_array_put_callback failed\n");
                    }
                    else
                    {   myDblPr[i] = 1;
                    }
                    
            }   
            
            status = ca_pend_io(MCA_PUT_TIMEOUT);
            
            break;    
                 
            
        case 100: // MCAMON install Monitor or replace MonitorCBString
            
            Hndl = (int)mxGetScalar(prhs[1]); 
            
            // Check if the handle is within range 
            if(Hndl<1 || Hndl>HandlesUsed)
            {   plhs[0]=mxCreateScalarDouble(0);
                mexErrMsgTxt("Invalid Handle");
            }
            
            if(CHNLS[Hndl-1].EVID) // if VID is not NULL - another monitor is already installed - replace MonitorCBString
            {   if(CHNLS[Hndl-1].MonitorCBString) // Free memory for occupied by the old MonitorCBString
                {   mxFree(CHNLS[Hndl-1].MonitorCBString);
                    CHNLS[Hndl-1].MonitorCBString = NULL;
                }
                if(nrhs>2) // Check if the new string is specified
                {   if(mxIsChar(prhs[2]))
                    {   buflen = mxGetM(prhs[2])*mxGetN(prhs[2])+1;
                        CHNLS[Hndl-1].MonitorCBString = (char *)mxMalloc(buflen);
                        mexMakeMemoryPersistent(CHNLS[Hndl-1].MonitorCBString);
                        mxGetString(prhs[2],CHNLS[Hndl-1].MonitorCBString,buflen); 
                    } 
                    else
                        mexErrMsgTxt("Third argument must be a string\n");
                }
                plhs[0]=mxCreateScalarDouble(1);
            }
            else // No monitor is presently installed;
            {   RequestType = dbf_type_to_DBR(ca_field_type(CHNLS[Hndl-1].CHID)); // Closest to the native 
            
            
                if(nrhs>2)
                {   if(mxIsChar(prhs[2]))
                    {   buflen = mxGetM(prhs[2])*mxGetN(prhs[2])+1;
                        CHNLS[Hndl-1].MonitorCBString = (char *)mxMalloc(buflen);
                        mexMakeMemoryPersistent(CHNLS[Hndl-1].MonitorCBString);
                        mxGetString(prhs[2],CHNLS[Hndl-1].MonitorCBString,buflen); 
                    } 
                    else
                        mexErrMsgTxt("Third argument must be a string\n");
                }
                else
                    CHNLS[Hndl-1].MonitorCBString = NULL;  // Set MonitorCBString to NULL so that mcaMonitorEventHandler only copies data to CACHE
            
                // Count argument set to 0 - native count
                status = ca_add_array_event(RequestType,0,CHNLS[Hndl-1].CHID, mcaMonitorEventHandler, &CHNLS[Hndl-1], 0.0, 0.0, 0.0, &(CHNLS[Hndl-1].EVID));
              
                if(status!=ECA_NORMAL)
                {   mexPrintf("ca_add_array_event failed\n");      
                    plhs[0]=mxCreateScalarDouble(0);
                }
                else
                {   ca_poll();
                    plhs[0]=mxCreateScalarDouble(1);
                }
            }   
            break;
            
        case 200: // Clear Monitor MCACLEARMON
            
            Hndl = (int)mxGetScalar(prhs[1]); 
            if(Hndl<1 || Hndl>HandlesUsed)
                mexErrMsgTxt("Invalid Handle");
            if(!CHNLS[Hndl-1].EVID) 
                mexErrMsgTxt("No monitor installed - can not clear");
                
            status = ca_clear_event(CHNLS[Hndl-1].EVID);
            if(status!=ECA_NORMAL)
                mexPrintf("ca_clear_event failed\n");
                
            // Set the EVID pointer to NULL (ca_clear_event dos not do it by itself)
            // to use as a FLAG that no monitors are installed 
            CHNLS[Hndl-1].EVID = NULL;
            // Reset
            CHNLS[Hndl-1].MonitorEventCount = 0;    
            // If there is Callback String - destroy it
            if(CHNLS[Hndl-1].MonitorCBString)
            {   mxFree(CHNLS[Hndl-1].MonitorCBString); 
                CHNLS[Hndl-1].MonitorCBString =NULL;
            }
                
          
        break;
          
        case 300: // MCACACHE Get Cached values of a monitored PV
            for(i=0;i<nrhs-1;i++)
            {   Hndl = (int)mxGetScalar(prhs[1+i]);
                // if(Hndl<1 || Hndl>HandlesUsed || !CHNLS[Hndl-1].CACHE)
                if(Hndl<1 || Hndl>HandlesUsed)
                    plhs[i] = mxCreateDoubleMatrix(0,0,mxREAL);
                else
                    {   plhs[i] = mxDuplicateArray(CHNLS[Hndl-1].CACHE);
                        CHNLS[Hndl-1].MonitorEventCount = 0;
                    }
            }       
          
        break;
        
        case 500: // MCAMON Info on installed monitors
            L = 0;
            HndlArray = (int*)mxCalloc(HandlesUsed,sizeof(int));
            
            for(i=0;i<HandlesUsed;i++) // Count installed monitors
            {   if(CHNLS[i].EVID)
                HndlArray[L++]=i+1;
            }       
            
            if(L>0)
            {   plhs[0] = mxCreateDoubleMatrix(1,L,mxREAL);
                myDblPr = mxGetPr(plhs[0]);
                plhs[1] = mxCreateCellMatrix(1,L);
                for(i=0;i<L;i++)
                {   myDblPr[i] = (double)HndlArray[i];
                    mxSetCell(plhs[1],i,mxCreateString(CHNLS[HndlArray[i]-1].MonitorCBString));
                }
            }
            else
            {   plhs[0] = mxCreateDoubleMatrix(0,0,mxREAL);
                plhs[1] = mxCreateCellMatrix(0,0);
            }
            
        break;
        
        case 510: // MCAMONEVENTS Event count fot monitors
                       
            plhs[0] = mxCreateDoubleMatrix(1,HandlesUsed,mxREAL);
            myDblPr = mxGetPr(plhs[0]);
            for(i=0;i<HandlesUsed;i++)
                myDblPr[i]=(double)(CHNLS[i].MonitorEventCount);
            
        break;
        
        case 1000: // print timeout settings
            plhs[0] = mxCreateDoubleMatrix(3,1,mxREAL);
            mexPrintf("MCA timeout settings\n:");
            mexPrintf("mcaopen\t%f [s]\n",  MCA_SEARCH_TIMEOUT );
            mexPrintf("mcaget\t%f [s]\n",  MCA_GET_TIMEOUT ); 
            mexPrintf("mcaput\t%f [s]\n",  MCA_PUT_TIMEOUT );

            myDblPr = mxGetPr(plhs[0]);
            myDblPr[0] = MCA_SEARCH_TIMEOUT;
            myDblPr[1] = MCA_GET_TIMEOUT;
            myDblPr[2] = MCA_PUT_TIMEOUT;

            
        break;
        
        
        case 1001: // set MCA_SEARCH_TIMEOUT
            // return delay value
            MCA_SEARCH_TIMEOUT = mxGetScalar(prhs[1]);
            plhs[0] = mxCreateScalarDouble(MCA_SEARCH_TIMEOUT);
        break;
        
        case 1002: // set MCA_GET_TIMEOUT
            // return delay value
            MCA_GET_TIMEOUT = mxGetScalar(prhs[1]);
            plhs[0] = mxCreateScalarDouble(MCA_GET_TIMEOUT);
        break;
        
        case 1003: // set MCA_PUT_TIMEOUT
            // return delay value
            MCA_PUT_TIMEOUT = mxGetScalar(prhs[1]);
            plhs[0] = mxCreateScalarDouble(MCA_PUT_TIMEOUT);
        break;

    } 
}
Esempio n. 17
0
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
  if ((nrhs == 0) || !mxIsChar(prhs[0])) {
    mexErrMsgTxt("BotParamClient: first argument must be command string");
  }
  if ((nrhs < 2) || !mxIsChar(prhs[1])) {
    mexErrMsgTxt("BotParamClient: second argument must be key");
  }

  std::string command = ::getString(prhs[0]);
  std::transform(command.begin(), command.end(), command.begin(), ::tolower);
  std::string key = ::getString(prhs[1]);

  if ((nrhs > 3) || ((nrhs == 3) && !::isSetCommand(command))) {
    mexErrMsgTxt("BotParamClient: too many input arguments");
  }

  if (isSetCommand(command) && (nrhs != 3)) {
    mexErrMsgTxt("BotParamClient: need value argument");
  }

  BotParam* param = BotParamClient::instance().getUnderlyingBotParam();
  if (param == NULL) {
    mexErrMsgTxt("BotParamClient: no param client; is server running?");
  }

  bool hasKey = (0 != bot_param_has_key(param, key.c_str()));
  if (!hasKey && !isSetCommand(command) && (command != "haskey")) {
    mexErrMsgTxt("BotParamClient: invalid key");
  }

  if (command == "haskey") {
    plhs[0] = mxCreateLogicalMatrix(1,1);
    mxLogical* out = mxGetLogicals(plhs[0]);
    out[0] = hasKey;
  }

  else if (command == "subkeys") {
    char** subkeysRaw = bot_param_get_subkeys(param, key.c_str());
    std::vector<std::string> subkeys;
    for (char** subkeyPtr = subkeysRaw; *subkeyPtr != NULL; ++subkeyPtr) {
      subkeys.push_back(std::string(*subkeyPtr));
    }
    bot_param_str_array_free(subkeysRaw);
    plhs[0] = mxCreateCellMatrix(1,subkeys.size());
    for (size_t i = 0; i < subkeys.size(); ++i) {
      mxSetCell(plhs[0], i, mxCreateString(subkeys[i].c_str()));
    }
  }

  else if (command == "getnum") {
    int len = bot_param_get_array_len(param, key.c_str());
    std::vector<double> vals;
    if (len <= 0) {
      double val;
      if (bot_param_get_double(param, key.c_str(), &val) != 0) {
        mexErrMsgTxt("BotParamClient: cannot find numeric");
      }
      vals.push_back(val);
    }
    else {
      vals.resize(len);
      if (bot_param_get_double_array(param, key.c_str(), vals.data(), len) != len) {
        mexErrMsgTxt("BotParamClient: non-numeric value(s)");
      }
    }
    plhs[0] = mxCreateDoubleMatrix(1,vals.size(),mxREAL);
    double* ptr = mxGetPr(plhs[0]);
    for (size_t i = 0; i < vals.size(); ++i) {
      ptr[i] = vals[i];
    }
  }

  else if (command == "getbool") {
    int len = bot_param_get_array_len(param, key.c_str());
    std::vector<bool> vals;
    if (len <= 0) {
      int val;
      if (bot_param_get_boolean(param, key.c_str(), &val) != 0) {
        mexErrMsgTxt("BotParamClient: cannot find bool");
      }
      vals.push_back(val!=0);
    }
    else {
      int valsRaw[len];
      if (bot_param_get_boolean_array(param, key.c_str(), valsRaw, len) != len) {
        mexErrMsgTxt("BotParamClient: non-boolean value(s)");
      }
      for (int i = 0; i < len; ++i) {
        vals.push_back(valsRaw[i]!=0);
      }
    }
    plhs[0] = mxCreateLogicalMatrix(1,vals.size());
    mxLogical* out = mxGetLogicals(plhs[0]);
    for (size_t i = 0; i < vals.size(); ++i) {
      out[i] = vals[i];
    }
  }

  else if (command == "getstr") {
    int len = bot_param_get_array_len(param, key.c_str());
    std::vector<std::string> vals;
    if (len <= 0) {
      char* val = NULL;
      if (bot_param_get_str(param, key.c_str(), &val) != 0) {
        mexErrMsgTxt("BotParamClient: cannot find string");
      }
      vals.push_back(std::string(val));
      free(val);
    }
    else {
      char** valsRaw = bot_param_get_str_array_alloc(param, key.c_str());
      for (char** valsPtr = valsRaw; *valsPtr != NULL; ++valsPtr) {
        vals.push_back(std::string(*valsPtr));
      }
      bot_param_str_array_free(valsRaw);
    }
    plhs[0] = mxCreateCellMatrix(1,vals.size());
    for (size_t i = 0; i < vals.size(); ++i) {
      mxSetCell(plhs[0], i, mxCreateString(vals[i].c_str()));
    }
  }

  else if (command == "setstr") {
    bot_param::set_t msg = constructSetMessage(param, key);
    std::string value;
    if (mxIsCell(prhs[2])) {
      int len = mxGetNumberOfElements(prhs[2]);
      for (int i = 0; i < len; ++i) {
        mxArray* cellVal = mxGetCell(prhs[2],i);
        if (!mxIsChar(cellVal)) {
          mexErrMsgTxt("BotParamClient: invalid string value argument");
        }
        std::string curVal = ::getString(cellVal);
        value += (curVal + std::string(","));
      }
      if (value.size() > 0) {
        value = value.substr(0,value.size()-1);
      }
      msg.entries[0].is_array = true;
    }
    else {
      if (!mxIsChar(prhs[2])) {
        mexErrMsgTxt("BotParamClient: invalid string value argument");
      }
      value = ::getString(prhs[2]);
    }
    msg.entries[0].value = value;
    BotParamClient::instance().getLcm()->publish("PARAM_SET", &msg);
  }

  else if (command == "setnum") {
    if (!mxIsDouble(prhs[2]) || mxIsComplex(prhs[2])) {
      mexErrMsgTxt("BotParamClient: third argument must be real value array");
    }
    bot_param::set_t msg = constructSetMessage(param, key);
    std::string value;
    int len = mxGetNumberOfElements(prhs[2]);
    double* valArray = mxGetPr(prhs[2]);
    for (int i = 0; i < len; ++i) {
      std::ostringstream oss;
      oss << valArray[i] << ",";
      value += oss.str();
    }
    if (value.size() > 0) {
      value = value.substr(0,value.size()-1);
    }
    msg.entries[0].value = value;
    msg.entries[0].is_array = (len > 1);
    BotParamClient::instance().getLcm()->publish("PARAM_SET", &msg);
  }

  else if (command == "print") {
    bot_param_write(param, stderr);
  }

  else {
    mexErrMsgTxt("BotParamClient: command must be haskey, subkeys, getnum, getbool, getstr, or setstr");
  }
}
Esempio n. 18
0
  bool mat_load_multi_array_vec2(MATFile *f, QString qsVarName, std::vector<std::vector<Array> > &vvA)
  {
    const char *name = 0;
    bool bRes = false;
    vvA.clear();

    if (f != 0) {
      mxArray *matlab_mat = matGetNextVariable(f, &name);
      std::cout << name << std::endl;

      bool bLoaded = false;

      while (matlab_mat != 0 && !bLoaded) {
        if (qsVarName == name) {
          if (mxIsCell(matlab_mat)) {
            mwSize cell_ndim = mxGetNumberOfDimensions(matlab_mat);
            const mwSize *cell_dims = mxGetDimensions(matlab_mat);
            //std::cout << "number of cell dimensions: " << cell_ndim << endl;

            assert(cell_ndim == 2);
            for (int dim_idx = 0; dim_idx < 2; ++dim_idx) {
              std::cout << "extent of cell dim " << dim_idx << ": " << cell_dims[dim_idx] << std::endl;
            }            

            uint N1 = cell_dims[0];
            uint N2 = cell_dims[1];            
            
            //vvA.resize(N1, std::vector<Array>(N2, Array()));

            for (uint i1 = 0; i1 < N1; ++i1) {
              vvA.push_back(std::vector<Array>());
              for (uint i2 = 0; i2 < N2; ++i2) {

                /* get dimensions of the current cell */
                mwIndex subs[2];
                subs[0] = i1;
                subs[1] = i2;
                mwIndex cell_idx = mxCalcSingleSubscript(matlab_mat, cell_ndim, subs);
                mxArray *E = mxGetCell(matlab_mat, cell_idx);

                mwSize mat_ndim = mxGetNumberOfDimensions(E);
                const mwSize *mat_dims = mxGetDimensions(E);
                //std::cout << "number of cell element dimensions: " << mat_ndim << endl;
                assert(mat_ndim == Array::dimensionality);

                /* copy from matlab matrix to Array */
                boost::array<typename Array::size_type, Array::dimensionality> array_shape;
                for (uint i = 0; i < Array::dimensionality; ++i) 
                  array_shape[i] = mat_dims[i];

                Array B(array_shape, boost::fortran_storage_order());  
                uint nElements = B.num_elements();

                if (nElements > 0) {
                  typename Array::element *data2 = B.data();
                  if (mxIsSingle(E)) {
                    float *pE = (float *)mxGetPr(E);
                    assert(pE != 0);
                    for (uint i = 0; i < nElements; ++i) {
                      *(data2 + i) = *pE;
                      ++pE;
                    }
                  }
                  else {
                    double *pE = mxGetPr(E);
                    assert(pE != 0);
                    for (uint i = 0; i < nElements; ++i) {
                      *(data2 + i) = *pE;
                      ++pE;
                    }
                  }

                  //vvA[i1][i2] = B;

                  /* copy to array with normal storage order */
                  // Array A = B; // this does not work!!! (storage order is of course copied at construction :)
                  Array A(array_shape);
                  A = B;
                  
                  vvA.back().push_back(A);
                }

              }
            }// cell elements

            bRes = true;
          }// is cell
          else {
            std::cout << "variable is not a cell array" << std::endl;
          }

          bLoaded = true;
        }

        mxDestroyArray(matlab_mat);
        matlab_mat = 0;

        if (!bLoaded)
          matlab_mat = matGetNextVariable(f, &name);

      }// variables
    }

    assert(bRes && "variable not found or could not open file");
    return bRes;
  }
Esempio n. 19
0
// Function definitions.
// -----------------------------------------------------------------
void mexFunction (int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
    int argc = 0;
    const char **argv;
    mwIndex i;
    int k, ncell;
    int j = 0;
    
    // Count inputs and check for char type
    
    for( k=0; k<nrhs; k++ )
    {
        if( mxIsCell( prhs[k] ) )
        {
            argc += ncell = mxGetNumberOfElements( prhs[k] );
            for( i=0; i<ncell; i++ )
                if( !mxIsChar( mxGetCell( prhs[k], i ) ) )
                    mexErrMsgTxt("Input cell element is not char");
        }
        else
        {
            argc++;
            if( !mxIsChar( prhs[k] ) )
                mexErrMsgTxt("Input argument is not char");
        }
    }
    // Construct argv
    
    argv = (const char **) mxCalloc( argc, sizeof(char *) );
    
    for( k=0; k<nrhs; k++ )
    {
        if( mxIsCell( prhs[k] ) )
        {
            ncell = mxGetNumberOfElements( prhs[k] );
            for( i=0; i<ncell; i++ )
                argv[j++] = mxArrayToString( mxGetCell( prhs[k], i )
                                            );
        }
        else
        {
            argv[j++] = mxArrayToString( prhs[k] );
        }
    }
    
    /*
    for(j = 0; j < argc; j++) {
        mexPrintf("Input %d = <%s>\n", j, argv[j]);
    }
    */
    
    
	try
	{  
		// list of ctl filenames and associated parameters
		CTLOperations ctl_operations;
        
		CTLParameters global_ctl_parameters;
		ctl_operation_t new_ctl_operation;
        
		// list of input images on which to operate
		std::list<const char *> input_image_files;
		char output_path[MAXPATHLEN + 1];
        
        Compression compression = Compression::compressionNamed("PIZ");
		format_t desired_format;
		format_t actual_format;
		float input_scale = 0.0;
		float output_scale = 0.0;
		bool force_overwrite_output_file = FALSE;
		bool noalpha = FALSE;
        
		int start_argc = argc;
        
		new_ctl_operation.filename = NULL;
                
		while (argc > 0)
		{
			if (!strncmp(argv[0], "-help", 2))
			{
				if (argc > 1)
				{
					usagePrompt(argv[1]);
				}
				else
				{
					usagePrompt(NULL);
				}
				return;
			}
            
			else if (!strncmp(argv[0], "-input_scale", 2))
			{
				if (argc == 1)
				{
					mexPrintf(
							"The -input_scale option requires an "
							"additional option specifying a scale\nvalue for the "
							"input file. see '-help scale' for additional "
							"details.\n");
					return;
				}
				else
				{
					char *end = NULL;
					input_scale = strtof(argv[1], &end);
					if (end != NULL && *end != 0)
					{
						mexPrintf(
								"Unable to parse '%s' as a floating "
								"point number for the '-input_scale'\nargument\n",
								argv[1]);
						return;
					}
					argv++;
					argc--;
				}
			}
			else if (!strncmp(argv[0], "-output_scale", 2))
			{
				if (argc == 1)
				{
					mexPrintf(
							"The -output_scale option requires an "
							"additional option specifying a scale\nvalue for the "
							"output file. see '-help scale' for additional "
							"details.\n");
					return;
				}
				else
				{
					char *end = NULL;
					output_scale = strtof(argv[1], &end);
					if (end != NULL && *end != 0)
					{
						mexPrintf(
								"Unable to parse '%s' as a floating "
								"point number for the '-output_scale'\nargument\n",
								argv[1]);
						return;
					}
					argv++;
					argc--;
				}
			}
			else if (!strncmp(argv[0], "-ctl", 3))
			{
				if (argc == 1)
				{
					mexPrintf(
							"the -ctl option requires an additional "
							"option specifying a file containing a\nctl script.\n"
							"see '-help ctl' for more details.\n");
					return;
				}
                
				if (new_ctl_operation.filename != NULL)
				{
					ctl_operations.push_back(new_ctl_operation);
				}
				new_ctl_operation.local.clear();
				new_ctl_operation.filename = argv[1];
                
				argv++;
				argc--;
			}
			else if (!strncmp(argv[0], "-format", 5))
			{
				if (argc == 1)
				{
					mexPrintf(
							"the -format option requires an additional "
							"argument specifying the destination file\nformat. "
							"this may be one of the following: 'dpx10', 'dpx16', "
							"'aces', 'tiff8',\n'tiff16', or 'exr'.\nSee '-help "
							"format' for more details.\n");
					return;
				}
				desired_format = find_format(argv[1]," for parameter '-format'.\nSee '-help format' for more details.");
				argv++;
				argc--;
			}
            else if (!strncmp(argv[0], "-compression", 3))
            {
                if (argc == 1)
                {
                    mexPrintf(
                            "the -compression option requires an additional "
                            "argument specifying a compression scheme to be "
                            "used.\n See '-help compression' for more details.\n");
                    return;
                }
                char scheme[8];
                memset(scheme, '\0', 8);
                for(int i = 0; i < 8 && argv[1][i]; ++i) {
                    scheme[i] = toupper(argv[1][i]);
                }
                compression = Compression::compressionNamed(scheme);
                if (!strcmp(compression.name, Compression::no_compression.name)) {
                    mexPrintf("Unrecognized compression scheme '%s'. Turning off compression.\n", scheme);
                }
                argv++;
                argc--;
            }
			else if (!strcmp(argv[0], "-param1") || !strcmp(argv[0], "-p1"))
			{
				if (argc < 3)
				{
					mexPrintf(
							"the -param1 option requires two additional "
							"arguments specifying the\nparameter name and value."
							"\nSee '-help param' for more details.\n");
					return;
				}
				if (new_ctl_operation.filename == NULL)
				{
					THROW(Iex::ArgExc, "the -param1 argument must occur *after* a -ctl option.");
				}
				new_ctl_operation.local.push_back(get_ctl_parameter(&argv, &argc, start_argc, "local", 1));
			}
			else if (!strcmp(argv[0], "-param2") || !strcmp(argv[0], "-p2"))
			{
				if (argc < 4)
				{
					mexPrintf(
							"the -param2 option requires three additional "
							"arguments specifying the\nparameter name and value."
							"\nSee '-help param' for more details.\n");
					return;
                    
				}
				if (new_ctl_operation.filename == NULL)
				{
					THROW(Iex::ArgExc, "the -param2 argument must occur *after* a -ctl option.");
				}
				new_ctl_operation.local.push_back(get_ctl_parameter(&argv, &argc, start_argc, "local", 3));
			}
			else if (!strcmp(argv[0], "-param3") || !strcmp(argv[0], "-p3"))
			{
				if (argc < 5)
				{
					mexPrintf(
							"the -param3 option requires four additional "
							"arguments specifying the\nparameter name and value."
							"\nSee '-help param' for more details.\n");
					return;
				}
				if (new_ctl_operation.filename == NULL)
				{
					THROW(Iex::ArgExc, "the -param3 argument must occur *after* a -ctl option.");
				}
				new_ctl_operation.local.push_back(get_ctl_parameter(&argv, &argc, start_argc, "local", 3));
			}
			else if (!strcmp(argv[0], "-global_param1") || !strcmp(argv[0], "-gp1"))
			{
				if (argc < 3)
				{
					mexPrintf("the -global_param1 option requires two "
							"additional arguments specifying the\nparameter "
							"name and value.\nSee '-help param' for more "
							"details.\n");
					return;
				}
				global_ctl_parameters.push_back(get_ctl_parameter(&argv, &argc, start_argc, "global", 1));
			}
			else if (!strcmp(argv[0], "-global_param2") || !strcmp(argv[0], "-gp2"))
			{
				if (argc < 4)
				{
					mexPrintf("the -global_param2 option requires three "
							"additional arguments specifying the\nparameter "
							"name and value.\nSee '-help param' for more "
							"details.\n");
					return;
				}
				global_ctl_parameters.push_back(get_ctl_parameter(&argv, &argc, start_argc, "global", 2));
			}
			else if (!strcmp(argv[0], "-global_param3") || !strcmp(argv[0], "-gp3"))
			{
				if (argc < 5)
				{
					mexPrintf("the -global_param3 option requires four "
							"additional arguments specifying the\nparameter "
							"name and value.\nSee '-help param' for more "
							"details.\n");
					return;
                    
				}
				global_ctl_parameters.push_back(get_ctl_parameter(&argv, &argc, start_argc, "global", 2));
			}
			else if (!strncmp(argv[0], "-verbose", 2))
			{
				verbosity++;
			}
			else if (!strncmp(argv[0], "-quiet", 2))
			{
				verbosity--;
			}
			else if (!strncmp(argv[0], "-force", 5))
			{
				force_overwrite_output_file = TRUE;
			}
			else if (!strncmp(argv[0], "-noalpha", 2))
			{
				noalpha = TRUE;
			}
			else if (!strncmp(argv[0], "-", 1))
			{
				mexPrintf(
						"unrecognized option %s. see -help for a list "
						"of available options.\n", argv[0]);
				return;
			}
			else
			{
				input_image_files.push_back(argv[0]);
			}
            
            
			argv++;
			argc--;
            
            
            
		}  // end while

		if (new_ctl_operation.filename != NULL)
		{
			ctl_operations.push_back(new_ctl_operation);
		}
		if (input_image_files.size() < 2)
		{
			mexPrintf(
					"one or more source filenames and a destination "
					"file or directory must be\nprovided. if more than one "
					"source filenames is provided then the last argument\nmust "
					"be a directory. see -help for more details.\n");
			return;
		}
        
		char *output_slash = NULL;
		const char *outputFile = input_image_files.back();
		input_image_files.pop_back();
        
		struct stat file_status;
		if (stat(outputFile, &file_status) >= 0)
		{
			if (S_ISDIR(file_status.st_mode))
			{
				memset(output_path, 0, sizeof(output_path));
				strncpy(output_path, outputFile, MAXPATHLEN);
				outputFile = output_path;
				output_slash = output_path + strlen(output_path);
				if (*output_slash != '/')
				{
					*(output_slash++) = '/';
					*output_slash = 0;
				}
			}
			else if (S_ISREG(file_status.st_mode))
			{
				if (input_image_files.size() > 1)
				{
					mexPrintf(
							"When providing more than one source "
							"image the destination must be a\ndirectory.\n");
					return;
				}
				else
				{
					if (!force_overwrite_output_file)
					{
						mexPrintf(
								"The destination file %s already exists.\n"
								"Cravenly refusing to overwrite unless you supply "
								"the -force option.\n", outputFile);
						return;
					}
					else
					{
						// File exists, but we treat it as if it doesn't (see
						// if(output_slash==NULL) {...} down below...
						output_slash = NULL;
					}
				}
			}
			else
			{
				mexPrintf(
						"Specified destination is something other than "
						"a file or directory. That's\nprobably a bad idea.\n");
				return;
			}
		}
		else
		{
			if (errno != ENOENT)
			{
				mexPrintf("Unable to get information about %s (%s).\n", outputFile, strerror(errno));
				return;
			}
			if (input_image_files.size() != 1)
			{
				mexPrintf(
						"When specifying more than one source file "
						"you must specify the destination as\na directory "
						"that already exists.\nUnable to stat '%s' (%s)\n",
						outputFile, strerror(errno));
				return;
			}
		}
        
		if (output_slash == NULL)
		{
			// This is the case when our outputFile is a single file. We do a bunch
			// of sanity checking between the extension of the specified file
			// (if any) and the -format option (if any).
			char *dot = (char *) strrchr(outputFile, '.');
			if (dot == NULL && desired_format.ext == NULL)
			{
				mexPrintf(
						"You have not explicitly provided an output "
						"format, and the output file name\ndoes not not contain "
						"an extension. Please add an extension to the output "
						"file\nor use the -format option to specify the desired "
						"output format.\n");
				return;
			}
			else if (dot != NULL)
			{
				if (desired_format.ext == NULL)
				{
					actual_format = find_format(dot + 1,
							                    " specified implicitly (by "
									            "the extension) for\noutput file "
									            "format. Please fix this or use\n"
									            "the -format option to specify "
									            "the desired output format.\n");
				}
				else
				{
					// HACK aces format file type check
                    const char *ext = desired_format.ext;
                    static const char exrext[] = "exr";
                    if (!strcmp(ext, "aces"))
                        ext = exrext;
                        if (strcmp(ext, dot + 1) && !force_overwrite_output_file)
                        {
                            mexPrintf(
                                    "You have specified a destination file "
                                    "type with the -format option, but the\noutput "
                                    "file extension does not match the format "
                                    "specified by the -format option.\nCravenly "
                                    "refusing to do this unless you specify the "
                                    "-force option (which\nwill make the -format "
                                    "option take priority).\n");
                            return;
                        }
					actual_format = desired_format;
				}
			}
		}
        
		if (verbosity > 1)
		{
			mexPrintf("global ctl parameters:\n");
            
			CTLParameters temp_ctl_parameters;
			temp_ctl_parameters = global_ctl_parameters;
            
			while (temp_ctl_parameters.size() > 0)
			{
				ctl_parameter_t new_ctl_parameter = temp_ctl_parameters.front();
				temp_ctl_parameters.pop_front();
				mexPrintf("%17s:", new_ctl_parameter.name);
				for (int i = 0; i < new_ctl_parameter.count; i++)
				{
					mexPrintf(" %f", new_ctl_parameter.value[i]);
				}
				mexPrintf("\n");
			}
			mexPrintf("\n");
		}
        
		while (input_image_files.size() > 0)
		{
			const char *inputFile = input_image_files.front();
            
			if (output_slash != NULL)
			{
				const char *input_slash = strrchr(inputFile, '/');
				if (input_slash == NULL)
				{
					input_slash = (char *) inputFile;
				}
				else
				{
					input_slash++;
				}
				strcpy(output_slash, input_slash);
				char *dot = (char *) strrchr(outputFile, '.');
				if (dot != NULL)
				{
					dot++;
					if (desired_format.ext != NULL)
					{
						// HACK aces format file type check
                        const char *ext = desired_format.ext;
                        static const char exrext[] = "exr";
                        if (!strcmp(ext, "aces"))
                            ext = exrext;
                            strcpy(dot, ext);
                            actual_format = desired_format;
                            }
					else
					{
						actual_format = find_format(dot, " (determined from destination file extension).");
					}
				}
			}
            
			if (force_overwrite_output_file)
			{
				if (unlink(outputFile) < 0)
				{
					if (errno != ENOENT)
					{
						mexPrintf("Unable to remove existing file named "
								"'%s' (%s).\n", outputFile, strerror(errno));
						return;
					}
				}
			}
			if (access(outputFile, F_OK) >= 0)
			{
                mexPrintf("Cravenly refusing to overwrite the file '%s'.\n", outputFile);
				return;
			}
			actual_format.squish = noalpha;
			transform(inputFile, outputFile, input_scale, output_scale, &actual_format, &compression, ctl_operations, global_ctl_parameters);
			input_image_files.pop_front();
		}
        
        
	} catch (std::exception &e)
	{
		mexPrintf("exception thrown (oops...): %s\n", e.what());
	}
    
    /*
    if( argc )
    {
        for( j=argc-1; j>=0; j-- )
            mxFree( argv[j] );
        mxFree( argv );
    }
    */
}
Esempio n. 20
0
void formatMatrix(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
/*    if (nlhs < 1) {
        mexWarnMsgTxt("formatMatrix did not get an output argument, so not doing any real work.  Specify an output argument to do real work.");
        RETURN_NULL();
    }*/
    if (nrhs != 1 || !mxIsCell(*prhs) || !mxGetNumberOfDimensions(*prhs)) 
        mexErrMsgTxt("formatMatrix: needs one input argument of type cell");
    const int m = mxGetM(*prhs), n = mxGetN(*prhs);
    int i,j;
    static long outbuf_len = 1024*1024; // preallocate 1MB
    char *outbuf = (char *)mxCalloc(outbuf_len, sizeof(char)), *outbufPtr = outbuf; // preallocate 1MB for output
    if (!outbuf)
        mexErrMsgTxt("formatMatrix: failed to allocate 1MB for output txt");
    for (i = 0; i < m; ++i) {
        for (j = 0; j < n; ++j) {
            int subs[2] = { i, j };
            char buf[4096];
            mxArray *cell = mxGetCell(*prhs, mxCalcSingleSubscript(*prhs, 2, subs));
            if (!cell) {
                mxFree(outbuf);
                mexErrMsgTxt("formatMatrix: A cell element in the cell array could not be retrieved!");
            }
            void *data = mxGetData(cell);
            if (!data) { // can happen on empty array
                mxFree(outbuf);
                mexErrMsgTxt("formatMatrix: A cell element in the cell array is empty/null -- all elements need to contain data!");
            }
            switch(mxGetClassID(cell)) {
                case mxCHAR_CLASS: 
                    mxGetString(cell, buf, sizeof(buf));
                    buf[sizeof(buf)-1] = 0;
                    break;
                case mxINT8_CLASS:   sprintf(buf, "%hhd", *(char *)mxGetData(cell)); break; 
                case mxUINT8_CLASS:  sprintf(buf, "%hhu", *(unsigned char *)mxGetData(cell)); break; 
                case mxINT16_CLASS:  sprintf(buf, "%hd", *(short *)mxGetData(cell)); break; 
                case mxUINT16_CLASS: sprintf(buf, "%hu", *(unsigned short *)mxGetData(cell)); break; 
                case mxINT32_CLASS:  sprintf(buf, "%d", *(int *)mxGetData(cell)); break; 
                case mxUINT32_CLASS: sprintf(buf, "%u", *(unsigned int *)mxGetData(cell)); break; 
                case mxSINGLE_CLASS: sprintf(buf, "%g", *(float *)mxGetData(cell)); break; 
                case mxDOUBLE_CLASS: sprintf(buf, "%g", *(double *)mxGetData(cell)); break; 
                default:
                    mxFree(outbuf);
                    mexErrMsgTxt("formatMatrix: Unknown cell type encountered!");
            }
            long lenSoFar = outbufPtr - outbuf;
            if (lenSoFar + (strlen(buf)*3+4) >= outbuf_len) {
                // reallocate if ran out of space
                void * tmp = mxRealloc(outbuf, outbuf_len*=2);
                if (!tmp) {
                    mxFree(outbuf);
                    mexErrMsgTxt("formatMatrix: Out of space in output text buffer and failed to allocate more!");
                }
                outbuf = (char *)tmp;
                outbufPtr = outbuf + lenSoFar;
            }
            // it's 1 cell per line....
            *outbufPtr++ = ' ';
            *outbufPtr++ = ' ';
            outbufPtr += UrlEncode(outbufPtr, buf);
            *outbufPtr++ = '\n';
        }
    }
   // return the text..
   if (plhs[0])
       mxDestroyArray(plhs[0]);
   plhs[0] = mxCreateString(outbuf);
   mxFree(outbuf);
}
int isFunctionHandle( const mxArray* const M )
{
	if ( M == NULL )
		return 0;

	if ( mxIsCell(M) )
		return 0;

	if ( mxIsChar(M) )
		return 0;

	if ( mxIsComplex(M) )
		return 0;

	if ( mxIsDouble(M) )
		return 0;

	if ( mxIsEmpty(M) )
		return 0;

	if ( mxIsInt8(M) )
		return 0;

	if ( mxIsInt16(M) )
		return 0;

	if ( mxIsInt32(M) )
		return 0;

	if ( mxIsLogical(M) )
		return 0;

	if ( mxIsLogicalScalar(M) )
		return 0;

	if ( mxIsLogicalScalarTrue(M) )
		return 0;

	if ( mxIsNumeric(M) )
		return 0;

	if ( mxIsSingle(M) )
		return 0;

	if ( mxIsSparse(M) )
		return 0;

	if ( mxIsStruct(M) )
		return 0;

	if ( mxIsUint8(M) )
		return 0;

	if ( mxIsUint16(M) )
		return 0;

	if ( mxIsUint32(M) )
		return 0;

	// assume to be a function handle iff it is nothing else
	return 1;
}
Esempio n. 22
0
mxArray* ParseChildNodes(pugi::xml_node& node)
{
    mxArray *children = NULL;
    pugi::xml_attribute tempAttr = node.first_attribute();

    if (HasChildNodes(node) || tempAttr != NULL)
    {
        mxArray *attributes = ParseAttributes(node);

        std::vector<std::string> distinctNames;
        std::vector<std::string> allChildNodeNames;
        std::vector<pugi::xml_node> childNodes;
        std::size_t numChildNodes;

        childNodes = GetChildNodes(node);
        numChildNodes = childNodes.size();

        for (int i = 0; i < numChildNodes; i++)
        {
            allChildNodeNames.push_back(childNodes.at(i).name());
        }

        distinctNames = GetDistinctNodeNames(allChildNodeNames);
        
        /* Patch for bypassing the variable-length arrays problems of modern C++ compilers */
        std::vector<const char*> distinctChildNodeNames;
        std::transform(distinctNames.begin(), distinctNames.end(), std::back_inserter(distinctChildNodeNames), [](const std::string & str) {
            // initialize empty char array
            char *output = new char[str.size()+1];
            std::strcpy(output, str.c_str());
            return output;
        });        

        std::vector<std::string> processedNames;

        children = mxCreateStructMatrix(1, 1, (int)distinctNames.size(), &distinctChildNodeNames[0]);

        for (int idx = 0; idx < childNodes.size(); idx++)
        {
            pugi::xml_node theChild = childNodes.at(idx);
            std::string type = node_types[theChild.type()];
            std::string temp = theChild.name();
            std::string val = theChild.value();

            const char *namey[1] = {};
            namey[0] = temp.c_str();
            mxArray *glhf = mxGetField(children, 0, namey[0]);
            int indexOfMatchingItem = mxGetFieldNumber(children,  namey[0]);

            if (!(strcmp(type.c_str(), "pcdata") == 0) && !(strcmp(type.c_str(), "comment") == 0) && !(strcmp(type.c_str(), "cdata") == 0))
            {
                //XML allows the same elements to be defined multiple times, put each in a different cell
                if (std::find(processedNames.begin(), processedNames.end(), temp) != processedNames.end())
                {
                    if ( glhf != NULL )
                    {
                        if (!mxIsCell(glhf))
                        {
                            mxArray *temp = glhf;
                            glhf = mxCreateCellMatrix(1, 2);
                            mxSetCell(glhf, 0, temp);
                            mxSetCell(glhf, 1, ParseChildNodes(theChild));
                            mxSetCell(children, indexOfMatchingItem, glhf);
                        }
                        else
                        {
                            std::size_t numberItemsInCell = mxGetN(glhf);
                            mxArray *temp = glhf;
                            glhf = mxCreateCellMatrix(1, numberItemsInCell + 1);

                            for (int i = 0; i < numberItemsInCell; i++)
                            {
                                mxSetCell(glhf, i, mxGetCell(temp, i));
                            }

                            mxSetCell(glhf, numberItemsInCell, ParseChildNodes(theChild));
                            mxSetCell(children, indexOfMatchingItem, glhf);
                        }
                    }
                }
                //add previously unknown (new) element to the structure
                else
                {
                    mxSetCell(children, indexOfMatchingItem, ParseChildNodes(theChild));
                }

                processedNames.push_back(temp);
            }
            else
            {
                const char *typeFieldNames[1] = {"Text"};
                std::string value  = theChild.value();
                mxArray *matValue  = mxCreateString(value.c_str());

                if (strcmp(type.c_str(), "cdata") == 0)
                {
                    typeFieldNames[0] = "CDATA";
                }
                else if (strcmp(type.c_str(), "comment") == 0)
                {
                    typeFieldNames[0] = "Comment";
                }

                children = mxCreateStructMatrix(1, 1, 1, typeFieldNames);
                mxSetFieldByNumber(children, 0, 0, matValue);

                processedNames.push_back(temp);
            }
        }

        if (attributes != NULL)
        {
            const char *attrFieldName = "Attributes";
            mxAddField(children, attrFieldName);
            mxSetField(children, 0, attrFieldName, attributes);
        }

    }

    return children;
}
void mexFunction( int nlhs,   mxArray  *plhs[], 
                  int nrhs,   const mxArray  *prhs[] )

{    
     mxArray  *rhs[2]; 
     mxArray  *blk_cell_pr, *A_cell_pr;
     double   *A,  *B,  *blksize;
     mwIndex  *irA, *jcA, *irB, *jcB;
     mwIndex  *cumblksize, *blknnz;
     mwSize   iscellA, mblk, mA, nA, m1, n1, rowidx, colidx, isspA, isspB;

     mwIndex  subs[2];
     mwSize   nsubs=2; 
     mwSize   n, n2, k, nsub, index, numblk, NZmax;
     double   ir2=1/sqrt(2); 

/* CHECK FOR PROPER NUMBER OF ARGUMENTS */

     if (nrhs < 2){
         mexErrMsgTxt("mexsmat: requires at least 2 input arguments."); }
     else if (nlhs>1){ 
         mexErrMsgTxt("mexsmat: requires 1 output argument."); }

/* CHECK THE DIMENSIONS */

     iscellA = mxIsCell(prhs[1]); 
     if (iscellA) { mA = mxGetM(prhs[1]); nA = mxGetN(prhs[1]); }
     else         { mA = 1; nA = 1; }
     if (mxGetM(prhs[0]) != mA) {
         mexErrMsgTxt("mexsmat: blk and Avec not compatible"); }

/***** main body *****/ 
       
     if (nrhs > 3) {rowidx = (mwSize)*mxGetPr(prhs[3]); } else {rowidx = 1;}  
     if (rowidx > mA) {
         mexErrMsgTxt("mexsmat: rowidx exceeds size(Avec,1)."); }
     subs[0] = rowidx-1;  /* subtract 1 to adjust for Matlab index */
     subs[1] = 1;
     index = mxCalcSingleSubscript(prhs[0],nsubs,subs); 
     blk_cell_pr = mxGetCell(prhs[0],index);
     if (blk_cell_pr == NULL) { 
        mexErrMsgTxt("mexsmat: blk not properly specified"); }    
     numblk  = mxGetN(blk_cell_pr);            
     blksize = mxGetPr(blk_cell_pr);
     cumblksize = mxCalloc(numblk+1,sizeof(mwSize)); 
     blknnz = mxCalloc(numblk+1,sizeof(mwSize)); 
     cumblksize[0] = 0; blknnz[0] = 0; 
     n = 0;  n2 = 0; 
     for (k=0; k<numblk; ++k) {
          nsub = (mwSize) blksize[k];
          n  += nsub; 
          n2 += nsub*(nsub+1)/2;  
          cumblksize[k+1] = n; 
          blknnz[k+1] = n2;
     }
     /***** assign pomwSizeers *****/
     if (iscellA) { 
         subs[0] = rowidx-1; 
         subs[1] = 0;
         index = mxCalcSingleSubscript(prhs[1],nsubs,subs); 
         A_cell_pr = mxGetCell(prhs[1],index); 
         A  = mxGetPr(A_cell_pr); 
         m1 = mxGetM(A_cell_pr); 
         n1 = mxGetN(A_cell_pr);
         isspA = mxIsSparse(A_cell_pr);
         if (isspA) { irA = mxGetIr(A_cell_pr);
                      jcA = mxGetJc(A_cell_pr); } 
     } else { 
         A  = mxGetPr(prhs[1]); 
         m1 = mxGetM(prhs[1]); 
         n1 = mxGetN(prhs[1]); 
         isspA = mxIsSparse(prhs[1]); 
         if (isspA) {  irA = mxGetIr(prhs[1]); 
                       jcA = mxGetJc(prhs[1]); }
     }
     if (numblk > 1) 
        { isspB = 1; }
     else { 
        if (nrhs > 2) {isspB = (mwSize)*mxGetPr(prhs[2]);} else {isspB = isspA;} 
     }
     if (nrhs > 4) {colidx = (mwSize)*mxGetPr(prhs[4]) -1;} else {colidx = 0;} 
     if (colidx > n1) { 
         mexErrMsgTxt("mexsmat: colidx exceeds size(Avec,2)."); 
     }    
     /***** create return argument *****/
     if (isspB) {
	 if (isspA) { NZmax = jcA[colidx+1]-jcA[colidx]; } 
         else       { NZmax = blknnz[numblk]; } 
	 rhs[0] = mxCreateSparse(n,n,2*NZmax,mxREAL); 
	 B = mxGetPr(rhs[0]); irB = mxGetIr(rhs[0]); jcB = mxGetJc(rhs[0]);
     } else {
         plhs[0] = mxCreateDoubleMatrix(n,n,mxREAL); 
         B = mxGetPr(plhs[0]); 
     }
     /***** Do the computations in a subroutine *****/
     if (numblk == 1) { 
         smat1(n,ir2,A,irA,jcA,isspA,m1,colidx,B,irB,jcB,isspB);  }
     else { 
         smat2(n,numblk,cumblksize,blknnz,ir2,A,irA,jcA,isspA,m1,colidx,B,irB,jcB,isspB);  
     }
     if (isspB) {
        /*** if isspB, (actual B) = B+B' ****/ 
        mexCallMATLAB(1, &rhs[1], 1, &rhs[0], "transpose"); 
        mexCallMATLAB(1, &plhs[0],2, rhs, "+");  
        mxDestroyArray(*rhs); 
     }
 return;
 }
Esempio n. 24
0
void mexFunction(int nlhs,   mxArray  *plhs[], 
                 int nrhs,   const mxArray  *prhs[] )

{    double   *A, *y;
     mwIndex  *irA, *jcA, *iry, *jcy; 
     double   *ytmp, *Ay;
     int      isspA, isspy, options;

     int      m1, n1, m2, n2, j, jm1; 
     int      i, r, k, istart, iend, kstart, kend;
     double   tmp; 

/* CHECK THE DIMENSIONS */

   if (mxIsCell(prhs[0]) | mxIsCell(prhs[1])) { 
       mexErrMsgTxt(" mexMatvec: A, x must be a double array"); }
   if (nrhs <2) {
       mexErrMsgTxt(" mexMatvec: must have at least 2 inputs"); }
   if (nlhs > 2) { 
       mexErrMsgTxt("mexMatvec: requires 1 output argument"); }
   if (nrhs == 2) { options = 0; } 
   else { options = (int) *mxGetPr(prhs[2]); } 


   /***** assign pointers *****/

       A = mxGetPr(prhs[0]); 
       m1 = mxGetM(prhs[0]); 
       n1 = mxGetN(prhs[0]);
       isspA = mxIsSparse(prhs[0]);
       if (isspA) { irA = mxGetIr(prhs[0]);
	            jcA = mxGetJc(prhs[0]); }
       isspy = mxIsSparse(prhs[1]);
       m2 = mxGetM(prhs[1]); 
       n2 = mxGetN(prhs[1]);            
       if (n2 > 1) { 
 	  mexErrMsgTxt("mexMatvec: 2ND input must be a column vector"); }
       if (isspy) { 
          iry = mxGetIr(prhs[1]);
          jcy = mxGetJc(prhs[1]); 
          ytmp = mxGetPr(prhs[1]); 
          /***** copy ytmp to y *****/ 
          y = mxCalloc(m2,sizeof(double)); 
          kstart = jcy[0]; kend = jcy[1]; 
          for (k=kstart; k<kend; k++) { 
	      r = iry[k]; y[r] = ytmp[k]; }
       } else {
          y = mxGetPr(prhs[1]); 
       }       
       if (options == 0 & n1 != m2) {
          mexErrMsgTxt("mexMatvec: 1ST and 2ND input not compatible."); 
       } else if (options & m1 != m2) {
          mexErrMsgTxt("mexMatvec: 1ST and 2ND input not compatible."); 
       }

       /***** create return argument *****/
       if (options==0) { 
          plhs[0] = mxCreateDoubleMatrix(m1,1,mxREAL); 
       } else { 
          plhs[0] = mxCreateDoubleMatrix(n1,1,mxREAL); 
       }
       Ay = mxGetPr(plhs[0]); 

    /***** main body *****/
    if (options==0) {
       if (!isspA) {
          for (j=0; j<n1; j++){ 
	     jm1 = j*m1;
             tmp = y[j]; 
             if (tmp !=0) { 
                saxpymat(A,jm1,0,m1,tmp,Ay,0); } 
	  }
       } else {
          for (j=0; j<n1; j++){
             tmp = y[j];
             if (tmp != 0) {
                istart = jcA[j]; iend = jcA[j+1]; 
  	        for (i=istart; i<iend; i++) {
                    r = irA[i]; 
	            Ay[r] += tmp*A[i]; }
	     }
	  }
       }
    } else {
       if (!isspA) {
          for (j=0; j<n1; j++){ 
            jm1 = j*m1; 
	    Ay[j] = realdotde(A,jm1,y,m1); 
	  }
       } else {
          for (j=0; j<n1; j++){
               istart = jcA[j]; iend = jcA[j+1]; 
               tmp = 0; 
  	       for (i=istart; i<iend; i++) {
                   r = irA[i]; 
	           tmp += y[r]*A[i]; }
               Ay[j] = tmp; 
	  }	  
       }
    }
 return;
}
Esempio n. 25
0
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
    mxArray* tmp;

    /* ================ */
    /* Check the INPUTS */
    /* ================ */
    #if DO_CHECK > 0
     if( nrhs != 4 )
        mexErrMsgIdAndTxt("InvalidInput:nrhs", "Require 4 inputs.");
    if ( !mxIsStruct(prhs[0]) )
        mexErrMsgIdAndTxt("InvalidInput:DICTIONARY", "'DICTIONARY' must be a struct");
    #endif

    mxArray* IC  = mxGetField( prhs[0], 0, "IC" );
    mxArray* EC  = mxGetField( prhs[0], 0, "EC" );
    mxArray* ISO = mxGetField( prhs[0], 0, "ISO" );
    #if DO_CHECK > 0
    if ( !mxIsStruct(IC) || !mxIsStruct(EC) || !mxIsStruct(ISO) )
        mexErrMsgIdAndTxt("InvalidInput:DICTIONARY", "'DICTIONARY' format is wrong");
    #endif

    // Parse "DICTIONARY.nV"
    tmp = mxGetField( prhs[0], 0, "nV" );
    #if DO_CHECK > 0
    if( !mxIsDouble(tmp) || mxIsComplex(tmp) ||  mxGetNumberOfElements(tmp)!=1 )
        mexErrMsgIdAndTxt("InvalidInput:DICTIONARY.nV","'DICTIONARY.nV' must be a real scalar");
    #endif
    nV = mxGetScalar( tmp );

    // Parse "DICTIONARY.EC.nE"
    tmp = mxGetField( EC, 0, "nE" );
    #if DO_CHECK > 0
    if( !mxIsDouble(tmp) || mxIsComplex(tmp) ||  mxGetNumberOfElements(tmp)!=1 )
        mexErrMsgIdAndTxt("InvalidInput:DICTIONARY.EC.nE","'DICTIONARY.EC.nE' must be a real scalar");
    #endif
    nE = mxGetScalar( tmp );

    // Parse "DICTIONARY.IC.n"
    tmp = mxGetField( IC, 0, "n" );
    #if DO_CHECK > 0
    if( !mxIsDouble(tmp) || mxIsComplex(tmp) ||  mxGetNumberOfElements(tmp)!=1 )
        mexErrMsgIdAndTxt("InvalidInput:DICTIONARY.IC.n","'DICTIONARY.IC.n' must be a real scalar");
    #endif
    n = mxGetScalar( tmp );

    // Parse "DICTIONARY.IC.fiber"
    tmp = mxGetField( IC, 0, "fiber" );
    #if DO_CHECK > 0
    if ( mxGetNumberOfDimensions(tmp) != 2 || mxGetN(tmp) != 1 || !mxIsClass(tmp,"uint32") )
        mexErrMsgIdAndTxt("InvalidInput:DICTIONARY.IC.fiber","'DICTIONARY.IC.fiber' must be a n*1 vector (uint32)");
    #endif
     ICf = (UINT32_T*) mxGetData( tmp );

    // Parse "DICTIONARY.IC.len"
    tmp = mxGetField( IC, 0, "len" );
    #if DO_CHECK > 0
    if ( mxGetNumberOfDimensions(tmp) != 2 || mxGetN(tmp) != 1 || !mxIsClass(tmp,"single") )
        mexErrMsgIdAndTxt("InvalidInput:DICTIONARY.IC.len","'DICTIONARY.IC.len' must be a n*1 vector (single)");
    #endif
     ICl = (float*) mxGetData(tmp);

    // Parse "DICTIONARY.IC.v", "DICTIONARY.IC.o"
    tmp = mxGetField( IC, 0, "v" );
    #if DO_CHECK > 0
    if ( mxGetNumberOfDimensions(tmp) != 2 || mxGetN(tmp) != 1 || !mxIsClass(tmp,"uint32") )
        mexErrMsgIdAndTxt("InvalidInput:DICTIONARY.IC.v","'DICTIONARY.IC.v' must be a n*1 vector (uint32)");
    #endif
    ICv = (UINT32_T*) mxGetData(tmp);
    tmp = mxGetField( IC, 0, "o" );
    #if DO_CHECK > 0
    if ( mxGetNumberOfDimensions(tmp) != 2 || mxGetN(tmp) != 1 || !mxIsClass(tmp,"uint16") )
        mexErrMsgIdAndTxt("InvalidInput:DICTIONARY.IC.o","'DICTIONARY.IC.o' must be a n*1 vector (uint16)");
    #endif
    ICo = (UINT16_T*) mxGetData(tmp);

    // Parse "DICTIONARY.EC.v","DICTIONARY.EC.o"
    tmp = mxGetField( EC, 0, "v" );
    #if DO_CHECK > 0
    if ( mxGetNumberOfDimensions(tmp) != 2 || mxGetN(tmp) != 1 || !mxIsClass(tmp,"uint32") )
        mexErrMsgIdAndTxt("InvalidInput:DICTIONARY.EC.v","'DICTIONARY.EC.v' must be a n*1 vector (uint32)");
    #endif
    ECv = (UINT32_T*) mxGetData(tmp);
    tmp = mxGetField( EC, 0, "o" );
    #if DO_CHECK > 0
    if ( mxGetNumberOfDimensions(tmp) != 2 || mxGetN(tmp) != 1 || !mxIsClass(tmp,"uint16") )
        mexErrMsgIdAndTxt("InvalidInput:DICTIONARY.EC.o","'DICTIONARY.EC.o' must be a n*1 vector (uint16)");
    #endif
    ECo = (UINT16_T*) mxGetData(tmp);

    // Parse "DICTIONARY.ISO.v"
    tmp = mxGetField( ISO, 0, "v" );
    #if DO_CHECK > 0
    if ( mxGetNumberOfDimensions(tmp) != 2 || mxGetN(tmp) != 1 || !mxIsClass(tmp,"uint32") )
        mexErrMsgIdAndTxt("InvalidInput:DICTIONARY.ISO.v","'DICTIONARY.ISO.v' must be a n*1 vector (uint32)");
    #endif
    ISOv = (UINT32_T*) mxGetData(tmp);

    // Parse "KERNELS.nS"
    tmp = mxGetField( prhs[1], 0, "nS" );
    #if DO_CHECK > 0
    if( !mxIsDouble(tmp) || mxIsComplex(tmp) ||  mxGetNumberOfElements(tmp)!=1 )
        mexErrMsgIdAndTxt("InvalidInput:KERNELS.nS","'KERNELS.nS' must be a real scalar");
    #endif
    nS = mxGetScalar( tmp );

    // Parse "KERNELS.wmr", "KERNELS.wmh" and "KERNELS.iso"
    mxArray* wmr = mxGetField( prhs[1], 0, "wmr" );
    #if nIC>=1
    #if DO_CHECK > 0
    if ( !mxIsCell(wmr) )
        mexErrMsgIdAndTxt("InvalidInput:KERNELS.wmr","'KERNELS.wmr' must be a cell array");
    if( !mxIsClass(mxGetCell(wmr,0),"single") )
        mexErrMsgIdAndTxt("InvalidInput:KERNELS.wmr","'KERNELS.wmr' must contain single");
    #endif
    wmrSFP0 = (float*) mxGetData( mxGetCell(wmr,0) );
    #endif
    #if nIC>=2
    #if DO_CHECK > 0
    if( !mxIsClass(mxGetCell(wmr,1),"single") )
        mexErrMsgIdAndTxt("InvalidInput:KERNELS.wmr","'KERNELS.wmr' must contain single");
    #endif
    wmrSFP1 = (float*) mxGetData( mxGetCell(wmr,1) );
    #endif
    #if nIC>=3
    #if DO_CHECK > 0
    if( !mxIsClass(mxGetCell(wmr,2),"single") )
        mexErrMsgIdAndTxt("InvalidInput:KERNELS.wmr","'KERNELS.wmr' must contain single");
    #endif
    wmrSFP2 = (float*) mxGetData( mxGetCell(wmr,2) );
    #endif
    #if nIC>=4
    #if DO_CHECK > 0
    if( !mxIsClass(mxGetCell(wmr,3),"single") )
        mexErrMsgIdAndTxt("InvalidInput:KERNELS.wmr","'KERNELS.wmr' must contain single");
    #endif
    wmrSFP3 = (float*) mxGetData( mxGetCell(wmr,3) );
    #endif

    #if nEC>=1
    mxArray* wmh = mxGetField( prhs[1], 0, "wmh" );
    #if DO_CHECK > 0
    if ( !mxIsCell(wmh) )
        mexErrMsgIdAndTxt("InvalidInput:KERNELS.wmh","'KERNELS.wmh' must be a cell array");
    if( !mxIsClass(mxGetCell(wmh,0),"single") )
        mexErrMsgIdAndTxt("InvalidInput:KERNELS.wmh","'KERNELS.wmh' must contain single");
    #endif
    wmhSFP0 = (float*) mxGetData( mxGetCell(wmh,0) );
    #if nEC>=2
    #if DO_CHECK > 0
    if( !mxIsClass(mxGetCell(wmh,1),"single") )
        mexErrMsgIdAndTxt("InvalidInput:KERNELS.wmh","'KERNELS.wmh' must contain single");
    #endif
    wmhSFP1 = (float*) mxGetData( mxGetCell(wmh,1) );
    #endif
    #if nEC>=3
    #if DO_CHECK > 0
    if( !mxIsClass(mxGetCell(wmh,2),"single") )
        mexErrMsgIdAndTxt("InvalidInput:KERNELS.wmh","'KERNELS.wmh' must contain single");
    #endif
    wmhSFP2 = (float*) mxGetData( mxGetCell(wmh,2) );
    #endif
    #if nEC>=4
    #if DO_CHECK > 0
    if( !mxIsClass(mxGetCell(wmh,3),"single") )
        mexErrMsgIdAndTxt("InvalidInput:KERNELS.wmh","'KERNELS.wmh' must contain single");
    #endif
    wmhSFP3 = (float*) mxGetData( mxGetCell(wmh,3) );
    #endif
    #endif

    #if nISO>=1
    mxArray* iso = mxGetField( prhs[1], 0, "iso" );
    #if DO_CHECK > 0
    if ( !mxIsCell(iso) )
        mexErrMsgIdAndTxt("InvalidInput:KERNELS.iso","'KERNELS.iso' must be a cell array");
    if( !mxIsClass(mxGetCell(iso,0),"single") )
        mexErrMsgIdAndTxt("InvalidInput:KERNELS.iso","'KERNELS.iso' must contain single");
    #endif
    isoSFP0 = (float*) mxGetData( mxGetCell(iso,0) );
    #if nISO>=2
    #if DO_CHECK > 0
    if( !mxIsClass(mxGetCell(iso,1),"single") )
        mexErrMsgIdAndTxt("InvalidInput:KERNELS.iso","'KERNELS.iso' must contain single");
    #endif
    isoSFP1 = (float*) mxGetData( mxGetCell(iso,1) );
    #endif
    #if nISO>=3
    #if DO_CHECK > 0
    if( !mxIsClass(mxGetCell(iso,2),"single") )
        mexErrMsgIdAndTxt("InvalidInput:KERNELS.iso","'KERNELS.iso' must contain single");
    #endif
    isoSFP2 = (float*) mxGetData( mxGetCell(iso,2) );
    #endif
    #if nISO>=4
    #if DO_CHECK > 0
    if( !mxIsClass(mxGetCell(iso,3),"single") )
        mexErrMsgIdAndTxt("InvalidInput:KERNELS.iso","'KERNELS.iso' must contain single");
    #endif
    isoSFP3 = (float*) mxGetData( mxGetCell(iso,3) );
    #endif
    #endif

    // Parse "x"
    #if DO_CHECK > 0
    if ( mxGetNumberOfDimensions(prhs[2]) != 2 || mxGetN(prhs[2]) != 1 || !mxIsClass(prhs[2],"double") )
        mexErrMsgIdAndTxt("InvalidInput:x","'x' must be a n*1 vector (double)");
    #endif
    x = (double*) mxGetData( prhs[2] );
    if ( nIC > 0 )
        nF = ( mxGetM(prhs[2]) - nE*nEC - nV*nISO) / nIC;
    else
        nF = 0;

    // parse "THREADS"
    #if DO_CHECK > 0
    if ( !mxIsStruct(prhs[3]) )
        mexErrMsgIdAndTxt("InvalidInput:THREADS", "'THREADS' must be a struct");
    #endif

    tmp  = mxGetField( prhs[3], 0, "IC" );
    #if DO_CHECK > 0
    if ( mxGetNumberOfDimensions(tmp) != 2 || mxGetN(tmp) != 1 || !mxIsClass(tmp,"uint32") )
        mexErrMsgIdAndTxt("InvalidInput:THREADS.IC","'THREADS.IC' must be a n*1 vector (uint32)");
    #endif
     ICthreads = (UINT32_T*) mxGetData( tmp );

    tmp  = mxGetField( prhs[3], 0, "EC" );
    #if DO_CHECK > 0
    if ( mxGetNumberOfDimensions(tmp) != 2 || mxGetN(tmp) != 1 || !mxIsClass(tmp,"uint32") )
        mexErrMsgIdAndTxt("InvalidInput:THREADS.EC","'THREADS.EC' must be a n*1 vector (uint32)");
    #endif
    ECthreads = (UINT32_T*) mxGetData( tmp );

    tmp  = mxGetField( prhs[3], 0, "ISO" );
    #if DO_CHECK > 0
    if ( mxGetNumberOfDimensions(tmp) != 2 || mxGetN(tmp) != 1 || !mxIsClass(tmp,"uint32") )
        mexErrMsgIdAndTxt("InvalidInput:THREADS.ISO","'THREADS.ISO' must be a n*1 vector (uint32)");
    #endif
    ISOthreads = (UINT32_T*) mxGetData( tmp );


    /* =============== */
    /* Set the OUTPUTS */
    /* =============== */
    #if DO_CHECK > 0
    if( nlhs != 1 )
        mexErrMsgIdAndTxt("InvalidOutput:nlhs", "Required 1 output.");
    #endif

    const int outDims[2] = { nS*nV, 1 };
    plhs[0] = mxCreateNumericArray(2, outDims, mxDOUBLE_CLASS, mxREAL);
    Y = (double*)mxGetData( plhs[0] );


    /* ================================================== */
    /* Run SEPARATE THREADS to perform the multiplication */
    /* ================================================== */
    pthread_t threads[nTHREADS];
    for(int t=0; t<nTHREADS ; t++)
        pthread_create( &threads[t], NULL, computeProductBlock, (void *) (long int)t );
    for(int t=0; t<nTHREADS ; t++)
        pthread_join( threads[t], NULL );

    return;
}
void mexFunction(int nlhs, mxArray *plhs[],
                 int nrhs, const mxArray *prhs[])
{
     unsigned n;
     double *x, *x0, opt_f;
     nlopt_result ret;
     mxArray *x_mx, *mx;
     user_function_data d, dpre, *dfc = NULL, *dh = NULL;
     nlopt_opt opt = NULL;

     CHECK(nrhs == 2 && nlhs <= 3, "wrong number of arguments");

     /* options = prhs[0] */
     CHECK(mxIsStruct(prhs[0]), "opt must be a struct");
     
     /* x0 = prhs[1] */
     CHECK(mxIsDouble(prhs[1]) && !mxIsComplex(prhs[1])
	   && (mxGetM(prhs[1]) == 1 || mxGetN(prhs[1]) == 1),
	   "x must be real row or column vector");
     n = mxGetM(prhs[1]) * mxGetN(prhs[1]),
     x0 = mxGetPr(prhs[1]);

     CHECK(opt = make_opt(prhs[0], n), "error initializing nlopt options");

     d.neval = 0;
     d.verbose = (int) struct_val_default(prhs[0], "verbose", 0);
     d.opt = opt;

     /* function f = prhs[1] */
     mx = struct_funcval(prhs[0], "min_objective");
     if (!mx) mx = struct_funcval(prhs[0], "max_objective");
     CHECK(mx, "either opt.min_objective or opt.max_objective must exist");
     if (mxIsChar(mx)) {
	  CHECK(mxGetString(mx, d.f, FLEN) == 0,
		"error reading function name string (too long?)");
	  d.nrhs = 1;
	  d.xrhs = 0;
     }
     else {
	  d.prhs[0] = mx;
	  strcpy(d.f, "feval");
	  d.nrhs = 2;
	  d.xrhs = 1;
     }
     d.prhs[d.xrhs] = mxCreateDoubleMatrix(1, n, mxREAL);

     if ((mx = struct_funcval(prhs[0], "pre"))) {
	  CHECK(mxIsChar(mx) || mxIsFunctionHandle(mx),
		"pre must contain function handles or function names");
	  if (mxIsChar(mx)) {
	       CHECK(mxGetString(mx, dpre.f, FLEN) == 0,
                     "error reading function name string (too long?)");
	       dpre.nrhs = 2;
	       dpre.xrhs = 0;
	  }
	  else {
	       dpre.prhs[0] = mx;
	       strcpy(dpre.f, "feval");
	       dpre.nrhs = 3;
	       dpre.xrhs = 1;
	  }
	  dpre.verbose = d.verbose > 2;
	  dpre.opt = opt;
	  dpre.neval = 0;
	  dpre.prhs[dpre.xrhs] = d.prhs[d.xrhs];
	  dpre.prhs[d.xrhs+1] = mxCreateDoubleMatrix(1, n, mxREAL);
	  d.dpre = &dpre;

	  if (struct_funcval(prhs[0], "min_objective"))
	       nlopt_set_precond_min_objective(opt, user_function,user_pre,&d);
	  else
	       nlopt_set_precond_max_objective(opt, user_function,user_pre,&d);
     }
     else {
	  dpre.nrhs = 0;
	  if (struct_funcval(prhs[0], "min_objective"))
	       nlopt_set_min_objective(opt, user_function, &d);
	  else
	       nlopt_set_max_objective(opt, user_function, &d);
     }

     if ((mx = mxGetField(prhs[0], 0, "fc"))) {
	  int j, m;
	  double *fc_tol;
	  
	  CHECK(mxIsCell(mx), "fc must be a Cell array");
	  m = mxGetM(mx) * mxGetN(mx);;
	  dfc = (user_function_data *) mxCalloc(m, sizeof(user_function_data));
	  fc_tol = struct_arrval(prhs[0], "fc_tol", m, NULL);

	  for (j = 0; j < m; ++j) {
	       mxArray *fc = mxGetCell(mx, j);
	       CHECK(mxIsChar(fc) || mxIsFunctionHandle(fc),
		     "fc must contain function handles or function names");
	       if (mxIsChar(fc)) {
		    CHECK(mxGetString(fc, dfc[j].f, FLEN) == 0,
		     "error reading function name string (too long?)");
		    dfc[j].nrhs = 1;
		    dfc[j].xrhs = 0;
	       }
	       else {
		    dfc[j].prhs[0] = fc;
		    strcpy(dfc[j].f, "feval");
		    dfc[j].nrhs = 2;
		    dfc[j].xrhs = 1;
	       }
	       dfc[j].verbose = d.verbose > 1;
	       dfc[j].opt = opt;
	       dfc[j].neval = 0;
	       dfc[j].prhs[dfc[j].xrhs] = d.prhs[d.xrhs];
	       CHECK(nlopt_add_inequality_constraint(opt, user_function,
						     dfc + j,
						     fc_tol ? fc_tol[j] : 0)
		     > 0, "nlopt error adding inequality constraint");
	  }
     }


     if ((mx = mxGetField(prhs[0], 0, "h"))) {
	  int j, m;
	  double *h_tol;
	  
	  CHECK(mxIsCell(mx), "h must be a Cell array");
	  m = mxGetM(mx) * mxGetN(mx);;
	  dh = (user_function_data *) mxCalloc(m, sizeof(user_function_data));
	  h_tol = struct_arrval(prhs[0], "h_tol", m, NULL);

	  for (j = 0; j < m; ++j) {
	       mxArray *h = mxGetCell(mx, j);
	       CHECK(mxIsChar(h) || mxIsFunctionHandle(h),
		     "h must contain function handles or function names");
	       if (mxIsChar(h)) {
		    CHECK(mxGetString(h, dh[j].f, FLEN) == 0,
		     "error reading function name string (too long?)");
		    dh[j].nrhs = 1;
		    dh[j].xrhs = 0;
	       }
	       else {
		    dh[j].prhs[0] = h;
		    strcpy(dh[j].f, "feval");
		    dh[j].nrhs = 2;
		    dh[j].xrhs = 1;
	       }
	       dh[j].verbose = d.verbose > 1;
	       dh[j].opt = opt;
	       dh[j].neval = 0;
	       dh[j].prhs[dh[j].xrhs] = d.prhs[d.xrhs];
	       CHECK(nlopt_add_equality_constraint(opt, user_function,
						     dh + j,
						   h_tol ? h_tol[j] : 0)
		     > 0, "nlopt error adding equality constraint");
	  }
     }


     x_mx = mxCreateDoubleMatrix(mxGetM(prhs[1]), mxGetN(prhs[1]), mxREAL);
     x = mxGetPr(x_mx);
     memcpy(x, x0, sizeof(double) * n);

     ret = nlopt_optimize(opt, x, &opt_f);

     mxFree(dh);
     mxFree(dfc);
     mxDestroyArray(d.prhs[d.xrhs]);
     if (dpre.nrhs > 0) mxDestroyArray(dpre.prhs[d.xrhs+1]);
     nlopt_destroy(opt);

     plhs[0] = x_mx;
     if (nlhs > 1) {
	  plhs[1] = mxCreateDoubleMatrix(1, 1, mxREAL);
	  *(mxGetPr(plhs[1])) = opt_f;
     }
     if (nlhs > 2) {
	  plhs[2] = mxCreateDoubleMatrix(1, 1, mxREAL);
	  *(mxGetPr(plhs[2])) = (int) ret;
     }
}
Esempio n. 27
0
//Check all inputs for size and type errors
void checkInputs(const mxArray *prhs[], int nrhs)
{
    size_t ndec, m, i;
    const mxArray *fxd;
    double *val;
    
    //Correct number of inputs
    if(nrhs < 3)
        mexErrMsgTxt("You must supply at least 3 arguments to dsdp (f, A, b)"); 
    
    //Check we have an objective
    if(mxIsEmpty(pF))
        mexErrMsgTxt("You must supply an objective function via f!");
    
    //Check we have some constraints
    if(nrhs >= (eSDP+1) && mxIsEmpty(pA) && mxIsEmpty(pLB) && mxIsEmpty(pUB) && mxIsEmpty(pSDP))
        mexErrMsgTxt("You must supply constraints to this solver!");
    else if(nrhs == (eUB+1) && mxIsEmpty(pA) && mxIsEmpty(pLB) && mxIsEmpty(pUB))
        mexErrMsgTxt("You must supply constraints to this solver!");
    else if(nrhs == (eB+1) && (mxIsEmpty(pA) || mxIsEmpty(pB)))
        mexErrMsgTxt("You must supply constraints to this solver!");
    
    //Check options is a structure
    if(nrhs > eOPTS && !mxIsStruct(pOPTS))
        mexErrMsgTxt("The options argument must be a structure");
    
    //Get Sizes
    ndec = mxGetNumberOfElements(pF);
    
    //Check linear constraints
    if(!mxIsEmpty(pA)) {
        //Check types
        if(!mxIsSparse(pA) || mxIsComplex(pA) || !mxIsDouble(pA))
            mexErrMsgTxt("A must be real, sparse, double matrix");
        if(mxIsSparse(pB) || mxIsComplex(pB) || !mxIsDouble(pB))
            mexErrMsgTxt("b must be real, dense, double column vector");
        //Check sizes
        if(mxGetN(pA) != ndec)
            mexErrMsgTxt("A does not have the same number of columns as decision variables!");
        if(mxGetM(pA) != mxGetNumberOfElements(pB))
            mexErrMsgTxt("A and b do not have the same number of rows!");        
    }
    //Check bounds
    if(nrhs > eLB && !mxIsEmpty(pLB)) {
        if(mxIsSparse(pLB) || mxIsComplex(pLB) || !mxIsDouble(pLB))
            mexErrMsgTxt("lb must be real, dense, double column vector");
        if(mxGetNumberOfElements(pLB) != ndec)
            mexErrMsgTxt("lb is not the same length as f!");
    }
    if(nrhs > eUB && !mxIsEmpty(pUB)) {
        if(mxIsSparse(pUB) || mxIsComplex(pUB) || !mxIsDouble(pUB))
            mexErrMsgTxt("ub must be real, dense, double column vector");
        if(mxGetNumberOfElements(pUB) != ndec)
            mexErrMsgTxt("ub is not the same length as f!");
    }
    //Check sdcones
    if(nrhs > eSDP && !mxIsEmpty(pSDP)) {
        if(mxIsCell(pSDP)) {
            for(i=0;i<mxGetNumberOfElements(pSDP);i++)
                checkCone(mxGetCell(pSDP,i),ndec,i);
        }
        else
            checkCone(pSDP,ndec,1);        
    }
    //Check y0
    if(nrhs > eY0 && !mxIsEmpty(pY0)) {
        if(mxIsSparse(pY0) || mxIsComplex(pY0) || !mxIsDouble(pY0))
            mexErrMsgTxt("y0 must be real, dense, double column vector");
        if(mxGetNumberOfElements(pY0) != ndec)
            mexErrMsgTxt("y0 is not the same length as f!");
    }
    //Check fixed vars option
    if(nrhs > eOPTS && !mxIsEmpty(pOPTS) && mxGetField(pOPTS,0,"fixed") && !mxIsEmpty(mxGetField(pOPTS,0,"fixed"))) {
        fxd = mxGetField(pOPTS,0,"fixed");
        //Check Type
        if(mxIsSparse(fxd) || mxIsComplex(fxd) || !mxIsDouble(fxd))
            mexErrMsgTxt("The fixed option must be a real, dense, double matrix");
        val = mxGetPr(fxd);
        m = mxGetM(fxd);
        if(mxGetN(fxd) != 2)
            mexErrMsgTxt("The fixed option must contain 2 columns");
        if(m > ndec)
            mexErrMsgTxt("The fixed option must not contain more rows than decision variables");
        for(i=0;i<m;i++) {
            if(val[i] <= 0 || val[i] > ndec)
                mexErrMsgTxt("A variable index in the fixed option is <= 0 or > ndec");
            if(mxIsNaN(val[i+m]) || mxIsInf(val[i+m]))
                mexErrMsgTxt("A variable value in the fixed option is NaN or Inf");            
        }
    }
}
Esempio n. 28
0
void mexFunction(int nlhs, mxArray *plhs[],
                 int nrhs, const mxArray *prhs[])
{
  const mxArray *srcmat;
  int ndim, eltsize;
  mwSize *dimsize;
  const mwSize *dims;
  int ndimdest;
  mwSize *destdims, *destdimsize;
  char *src, *dest;
  mwSize *rep;
  int i,nrep;
  int extra_rep = 1;
  int empty;
	double *outp, *inp;
	mwSize m,n,numel;

  if(nrhs < 2) mexErrMsgTxt("Usage: repmat(A, [M N ...])");
  srcmat = prhs[0];
	if(0) {
		/* testing code, please ignore */
		/*
		plhs[0] = mxCreateNumericArrayE(ndim, dims, mxGetClassID(srcmat), 
																		mxIsComplex(srcmat)?mxCOMPLEX:mxREAL);
																		*/
		m = mxGetM(srcmat);
		n = mxGetN(srcmat);		
		plhs[0] = mxCreateDoubleMatrixE(m, n, mxREAL);
		outp = mxGetPr(plhs[0]);
		inp = mxGetPr(srcmat);
		numel = mxGetNumberOfElements(srcmat);
		memcpy(outp, inp, numel*sizeof(double));
		/*
		plhs[0] = mxCreateNumericMatrixE(dims[0], dims[1], mxGetClassID(srcmat), 
																		mxIsComplex(srcmat)?mxCOMPLEX:mxREAL);
		plhs[0] = mxCreateNumericMatrix(0, 0, mxGetClassID(srcmat), 
																		mxIsComplex(srcmat)?mxCOMPLEX:mxREAL);
		*/
		return;
	}

  if(!mxIsNumeric(srcmat) || mxIsSparse(srcmat) || mxIsCell(srcmat) || mxIsStruct(srcmat)) {
    /* call Matlab's repmat */
    mexCallMATLAB(nlhs,plhs,nrhs,(mxArray**)prhs,"xrepmat");return;
    /* mexErrMsgTxt("Sorry, can't handle sparse matrices yet."); */
  }
  ndim = mxGetNumberOfDimensions(srcmat);
  dims = mxGetDimensions(srcmat);
  eltsize = mxGetElementSize(srcmat);
	
  /* compute dimension sizes */
  dimsize = (mwSize*)mxCalloc(ndim, sizeof(mwSize));
  dimsize[0] = eltsize*dims[0];
  for(i=1;i<ndim;i++) dimsize[i] = dimsize[i-1]*dims[i];

  /* determine repetition vector */
  ndimdest = ndim;
  if(nrhs == 2) {
    /* prhs[1] is a vector of reps */
    nrep = mxGetN(prhs[1]);
    if(nrep > ndimdest) ndimdest = nrep;
    rep = (mwSize*)mxCalloc(ndimdest, sizeof(mwSize));
    for(i=0;i<nrep;i++) {
      double repv = mxGetPr(prhs[1])[i];
      rep[i] = (mwSize)repv;
    }
#if ALWAYS_2D
    if(nrep == 1) {
      /* special behavior */
      nrep = 2;
      rep[1] = rep[0];
    }
#endif
  }
  else {
    /* concatenate all prhs's */
    int ri=0;
    nrep = 0;
    for(i=0;i<nrhs-1;i++) {
      nrep += mxGetNumberOfElements(prhs[i+1]);
    }
    if(nrep > ndimdest) ndimdest = nrep;
    rep = (mwSize*)mxCalloc(ndimdest, sizeof(mwSize));
    for(i=0;i<nrhs-1;i++) {
      double *p = mxGetPr(prhs[i+1]);
      int j, sz = mxGetNumberOfElements(prhs[i+1]);
      for(j=0;j<sz;j++) rep[ri++] = (mwSize)p[j];
    }
  }
  for(i=nrep;i<ndimdest;i++) rep[i] = 1;

  /* compute output size */
  destdims = (mwSize*)mxCalloc(ndimdest, sizeof(mwSize));
  for(i=0;i<ndim;i++) destdims[i] = dims[i]*rep[i];
  for(;i<ndimdest;i++) { 
    destdims[i] = rep[i];
    extra_rep *= rep[i];
  }
  destdimsize = (mwSize*)mxCalloc(ndim, sizeof(mwSize));
  destdimsize[0] = eltsize*destdims[0];
  for(i=1;i<ndim;i++) destdimsize[i] = destdimsize[i-1]*destdims[i];

  /* for speed, array should be uninitialized */
  plhs[0] = mxCreateNumericArrayE(ndimdest, destdims, mxGetClassID(srcmat), 
				  mxIsComplex(srcmat)?mxCOMPLEX:mxREAL);

  /* if any rep[i] == 0, output should be empty array.
     Added by KPM 11/13/02.
  */
  empty = 0;
  for (i=0; i < nrep; i++) {
    if (rep[i]==0) 
      empty = 1;
  }
  if (empty) 
    return;

  src = (char*)mxGetData(srcmat);
  dest = (char*)mxGetData(plhs[0]);
  repmat(dest,src,ndim,destdimsize,dimsize,dims,rep);
  if(ndimdest > ndim) memrep(dest,destdimsize[ndim-1],extra_rep);
  if(mxIsComplex(srcmat)) {
    src = (char*)mxGetPi(srcmat);
    dest = (char*)mxGetPi(plhs[0]);
    repmat(dest,src,ndim,destdimsize,dimsize,dims,rep);
    if(ndimdest > ndim) memrep(dest,destdimsize[ndim-1],extra_rep);
  }
}
Esempio n. 29
0
MP_Dict_c * mp_create_dict_from_mxDict(const mxArray *mxDict)
{
	const char						*func = "mp_create_dict_from_mxDict";
	const char						*fieldName;
	map<string,string,mp_ltstring>	*paramMap;
	MP_Dict_c						*dict = NULL;
	mxArray							*mxBlockCell,*mxBlock,*mxTmp;
	mwSize							mwNumDimension;
	const mwSize					*mwDimension;
	size_t							numFields;
	int								nBlocks;
	int								iIndexDimension,iDimension;
	char							*fieldValue;
	double							*dTable = NULL;
	string							szDataString,szReturnString;
				

	if (NULL==mxDict) 
	{
	    mp_error_msg(func,"input is NULL\n");
	    return(NULL);
	}
	
	// Check that the input dictionary structure has the right fields
	mxBlockCell = mxGetField(mxDict,0,"block");
	if (NULL==mxBlockCell) 
	{
		mp_error_msg(func,"the dict.block field is missing\n");
		return(NULL);
	}
	nBlocks = (int)mxGetNumberOfElements(mxBlockCell);
	if (0==nBlocks) 
	{
		mp_error_msg(func,"the number of blocks should be at least one\n");
		return(NULL);
	}
	if(!mxIsCell(mxBlockCell)) 
	{
		mp_error_msg(func,"the dict.block is not a cell array\n");
		return(NULL);
	}
	// Reach all blocks 
	for (int i = 0; i < nBlocks; i++ ) 
	{
		mxBlock = mxGetCell(mxBlockCell,i);
		if (NULL==mxBlock) 
		{ 
			// This should never happen
			mp_error_msg(func,"dict.block{%d} could not be retrieved\n",i+1);
			// Clean the house
			if(NULL!=dict) delete dict; 
			return(NULL);
		}
		numFields = mxGetNumberOfFields(mxBlock);
		if (0==numFields) 
		{
			mp_error_msg(func,"the number of fields %d should be at least one in dict.block{%d}\n",numFields,i+1);
			// Clean the house
			if(NULL!=dict) delete dict; 
			return(NULL);
		}
    
		// Reach all fields of the block and put them in a map
		paramMap = new map<string, string, mp_ltstring>();
		if(NULL==paramMap) 
		{
			mp_error_msg(func,"could not allocate paramMap\n");
			// Clean the house
			if(NULL!=dict) delete dict; 
			return(NULL);
		}
		for (unsigned int j= 0; j <numFields ; j++) 
		{
			fieldName = mxGetFieldNameByNumber(mxBlock,j);
			if (fieldName == NULL) 
			{
				mp_error_msg(func,"field number %d in dict.block{%d} could not be retrieved\n",j+1,i+1);
				// Clean the house
				if(NULL!=dict) delete dict; 
				return(NULL);
			}

			// Retrieve the field value 
			mxTmp = mxGetField(mxBlock,0,fieldName);
			if(mxTmp == NULL) 
			{
				mp_error_msg(func,"value of field number %d in dict.block{%d} could not be retrieved\n",j+1,i+1);
				// Clean the house
				if(NULL!=dict) delete dict; 
				return(NULL);
			}

			if(mxIsDouble(mxTmp)) 
			{
				// Retrieve the dimension of the double
				mwNumDimension = mxGetNumberOfDimensions(mxTmp);
				mwDimension = mxGetDimensions(mxTmp);
				iDimension = 1;
				for(iIndexDimension = 0; iIndexDimension < (int)mwNumDimension; iIndexDimension++)
					iDimension *= mwDimension[iIndexDimension];
				// Add the dimension of a double
				iDimension = iDimension * sizeof(double);
				// Getting the storage field
				if((dTable = (MP_Real_t*)malloc(iDimension)) == NULL)
				{
					mp_error_msg(func,"The double storage has not been allocaed\n");
					return(NULL);
				}
				// Loading the mxArray
				if(!mp_get_anywave_datas_from_mxAnywaveTable(mxBlock,dTable))
				{
					mp_error_msg(func,"A double value has been found but could not be retrieved\n");
					// Clean the house
					if(NULL!=dict) delete dict; 
					return(NULL);
				}
				// Store it in the map and free 
				(*paramMap)["doubledata"] = string((char *)dTable, iDimension);	
			}
			else
			{
				fieldValue = mxArrayToString(mxTmp);
				if(fieldValue == NULL) 
				{
					mp_error_msg(func,"string value of field number %d in dict.block{%d} could not be retrieved\n",j+1,i+1);
					// Clean the house
					if(NULL!=dict) delete dict; 
					return(NULL);
				}
				// Store it in the map and free 
				(*paramMap)[string(fieldName)]=string(fieldValue);
				mxFree(fieldValue);
				fieldValue = NULL;
			}
		}
    
		// Retrieve the block creator
		MP_Block_c* (*blockCreator)( MP_Signal_c *setSignal, map<string, string, mp_ltstring> * paramMap ) = NULL;
		blockCreator = MP_Block_Factory_c::get_block_creator((*paramMap)["type"].c_str());
		if (NULL == blockCreator) 
		{
			mp_error_msg(func,"the block factory does not contain type %s of dict.block{%d}\n",(*paramMap)["type"].c_str(),i+1);
			// Clean the house
			if(NULL!=dict) delete dict; 
			delete paramMap;
			return(NULL);
		}
		// Create the block 
		MP_Block_c *block =  blockCreator(NULL, paramMap);
		if (NULL == block) 
		{
			mp_error_msg(func,"the dict.block{%d}, of type %s was not successfully created\n",i+1,(*paramMap)["type"].c_str());
			// Clean the house
			if(NULL!=dict) delete dict; 
			delete paramMap;
			return(NULL);
		}
    	// Create the dictionary if needed (i.e. when adding first block)
		if (NULL==dict) 
		{
			dict = MP_Dict_c::init();
			if (NULL==dict) 
			{
				mp_error_msg(func,"Failed to create an empty dictionary\n");
				delete paramMap;
				delete block;
				return(NULL);
			}
		}
		// Add the block to the dictionary 
		dict->add_block(block);

		if(dTable) free(dTable);
		delete paramMap;
	}
	return(dict);
}
Esempio n. 30
0
void mexFunction(int nlhs, mxArray *plhs[],
                 int nrhs, const mxArray *prhs[])
{
    
    /* description:
     * given a set of reference stimuli and responses (forming a joint distribution),
     * this function will compute the log kernel density estimate over a grid of stimuli
     * for a set of test responses. Within kernel types a radial-symmetric kernel is used. Different kernels are combined multiplicatively.
     *
     * syntax:
     * out = kde_decode_general( stimulus, stimulus_grid, stimulus_kernel, stimulus_bandwidth, response, response_kernel, response_bandwidth, test_response[, offset[, distance[, timestamp, bins]]] );
     *
     * arguments:
     * stimulus = number of spikes x number of stimulus dimensions
     * stimulus_grid = number of grid elements x number of stimulus dimensions
     * stimulus_kernel = 1 x number of stimulus dimensions
     * stimulus_bandwidth = 1 x number of stimulus dimensions
     * response = number of spikes x number of response dimensions
     * response_kernel = 1 x number of response_dimensions
     * response_bandwidth = 1 x number of response dimensions
     * test_response = number of test spikes x number of response dimensions
     * offset = number of grid elements
     * distance = optional matrix of distances. If this argument is present (and not empty), the stimulus and stimulus_grid arguments should be given as a zero-based index into the distance matrix.
     * timestamp = number of test spikes x 1
     * bins = number of bins x 2
     *
     * out = number of test spikes x number of stimulus grid elements (if no timestamps and bins arguments are provided)
     * out = number of bins x number of stimulus grid elements (if timestamps and bins arguments are provided)
     *
     * kernels:
     * 0 = gaussian
     * 1 = epanechnikov
     * 2 = von mises
     * 3 = kronecker
     *
     */
    
    double cutoff = 2;             /* cut-off (in standard deviations) for gaussian kernel */
    double vm_cutoff = 0.1;        /* cut-off (probability) for von mises kernel */
    
    static const double pi = 3.141592653589793238462643383279502884197;
    
    /* INPUTS */
    double *stimulus;              /* NxQ */
    double *stimulus_grid;         /* GxQ */
    double *stimulus_kernel;       /* 1xQ */
    double *stimulus_bandwidth;    /* 1xQ */    
    double *response;              /* NxD or Nx0 or empty*/
    double *response_kernel;       /* 1xD */
    double *response_bandwidth;    /* 1xD */
    double *test_response;         /* MxD or Mx0 or empty*/
    double *timestamp;
    double *bins;
    double *stimulus_vonmises;
    double *response_vonmises;
    double *offset;
    
    /* VARIABLES */
    int N, D, M, Q, G, B;
    int n, d, m, q, g, b;
    int sizeM, loopM;
    int next_idx, idx;
    double *skip_g, *z;
    double acc_a_gauss, acc_a_epa, acc_a_delta, acc_a_vm;
    double *acc_g_gauss, *acc_g_epa, *acc_g_delta, *acc_g_vm;
    double tmp;
    double *pout, *pout2;
    mxArray *out, *out2;
    int idx1, idx2;
    
    mxArray *tmpmat;
    int *use_distance_lookup;
    int *NI;
    double **distance;

    int ngauss = 0;
    int nepa = 0;
    int nmises = 0;
    int nkron = 0;
    
    double scaling_factor = 1;
    double v;
    double c1, c2;
    
    mxArray *argout=NULL, *argin[2];
    double *pargin1;
    double *pargin2;

    
    /* CHECK NUMBER OF INPUTS */
    if (nrhs<4)
        mexErrMsgTxt("This function requires at least four input arguments");
    
    /* CHECK DIMENSIONS OF FIRST TWO ARGUMENTS */
    if ( mxGetNumberOfDimensions(prhs[0])!=2 || mxGetNumberOfDimensions(prhs[1])!=2)
        mexErrMsgTxt("stimulus and stimulus_grid input arguments need to be matrices");
    
    /* GET POINTERS TO FIRST FOUR ARGUMENTS */
    stimulus = mxGetPr( prhs[0] );
    stimulus_grid = mxGetPr( prhs[1] );
    stimulus_kernel = mxGetPr( prhs[2] );
    stimulus_bandwidth = mxGetPr( prhs[3] );

    /* GET ARRAY SIZES */
    N = mxGetM( prhs[0] );  /* number of source (encoding) spikes */
    Q = mxGetN( prhs[0] );  /* number of stimulus dimensions */
    G = mxGetM( prhs[1] );  /* number of points in stimulus grid */

    /* CHECK NUMBER OF DIMENSIONS IN STIMULUS GRID */
    if (mxGetN(prhs[1])!=Q)
        mexErrMsgTxt("Incompatible size of stimulus_grid input arguments");

    /* CHECK NUMBER OF STIMULUS KERNELS AND BANDWIDTHS */
    if (mxGetNumberOfElements(prhs[2])!=Q || mxGetNumberOfElements(prhs[3])!=Q)
        mexErrMsgTxt("Incompatible size of stimulus kernel and/or bandwidth arguments");
    
    
    /* CHECK OPTIONAL INPUTS */
    /* CHECK IF EITHER NO RESPONSE, OR RESPONSE + KERNEL + BANDWIDTH IS SPECIFIED */
    if (nrhs>5 && nrhs<7)
        mexErrMsgTxt("Specify response, response kernel and bandwidth arguments");
    
    if (nrhs>6) {
        /* CHECK DIMENSIONALITY OF SPIKE RESPONSE (ENCODING)*/
        if ( mxGetNumberOfDimensions(prhs[4])!=2 )
            mexErrMsgTxt("Response input argument needs to be a matrix");
        response = mxGetPr( prhs[4] );
        D = mxGetN( prhs[4] );  /* number of response dimensions */
        /* CHECK NUMBER OF SPIKES IN RESPONSE */
        if ( (D>0 && mxGetM(prhs[4])!=N ) )
            mexErrMsgTxt("Incompatible size of response input argument");
        response_kernel = mxGetPr( prhs[5] );
        response_bandwidth = mxGetPr( prhs[6] );
        /* CHECK NUMBER OF RESPONSE KERNELS AND BANDWIDTHS */
        if (mxGetNumberOfElements(prhs[5])!=D || mxGetNumberOfElements(prhs[6])!=D)
            mexErrMsgTxt("Incompatible size of response kernel and/or bandwidth arguments");
        
    } else {
        D = 0;  /* no response specified */
    }
        
    if (nrhs>7) {
        /* CHECK DIMENSIONALITY OF TEST RESPONSE (DECODING)*/
        if ( mxGetNumberOfDimensions(prhs[7])!=2 )
            mexErrMsgTxt("Test_response input argument needs to be a matrix");
        test_response = mxGetPr( prhs[7] );
        M = mxGetM( prhs[7] );  /* number of test (decoding) spikes */
        /* CHECK NUMBER OF DIMENSIONS IN TEST RESPONSE */
        if ( mxGetN(prhs[7])!=D )
            mexErrMsgTxt("Incompatible size of test_response input argument");
    } else {
        M = 0; /* no test spikes specified */
    }
    
    if ( D==0 && M==0 )
        M = 1;

    if (nrhs>8) {
        /* CHECK SIZE OF OFFSET VECTOR */
         if ( !mxIsDouble( prhs[8] ) || mxGetNumberOfElements( prhs[8] )!=G )
             mexErrMsgTxt("Incompatible size of offset vector");
        offset = mxGetPr( prhs[8] );
    } else {
        mexErrMsgTxt("Please provide offset vector");
    }    
    
    /* ALLOCATE ARRAYS FOR DISTANCE LOOK-UP TABLES */
    use_distance_lookup = (int*) mxCalloc( Q, sizeof(int) );
    distance = (double**) mxCalloc( Q, sizeof(double*) );
    NI = (int*) mxCalloc( Q, sizeof(int) ); /* size of distance LUTs */
    /* INITIALIZE ARRAY */
    for (q=0;q<Q;q++)
        use_distance_lookup[q] = 0;
    
    if (nrhs>9) {
        /* CHECK CLASS AND SIZE OF DISTANCE LUTs */
        if ( !mxIsCell( prhs[9] ) || mxGetNumberOfElements( prhs[9] )!=Q )
            mexErrMsgTxt("Distance input argument needs to be a cell array with as many cells as stimulus dimensions");
        
        for ( q=0 ; q<Q ; q++ ) {
            tmpmat = mxGetCell( prhs[9], q );
            if (tmpmat==NULL || mxIsEmpty(tmpmat)) {
                use_distance_lookup[q] = 0;
            } else {
                /* CHECK SIZE OF DISTANCE LUT */
                if ( mxGetNumberOfDimensions(tmpmat)!=2 || mxGetM( tmpmat )!=mxGetN( tmpmat ) ) 
                    mexErrMsgTxt("Distance arrays need to be square matrices");
                distance[q] = (double*) mxGetPr( tmpmat );
                NI[q] = mxGetM( tmpmat );
                use_distance_lookup[q] = true;
                /* when using distance LUT, the corresponding stimulus and stimulus grid should be indices into the LUT */
                /* CHECK IF STIMULUS AND STIMULUS_GRID >=0 && <NI[q] */
                for ( n=0; n<N; n++ ) {
                    if ( stimulus[n+q*N]<0 || stimulus[n+q*N]>=NI[q] )
                        mexErrMsgTxt("Invalid index");
                }
                for ( g=0; g<G; g++ ) {
                    if ( stimulus_grid[g+q*G]<0 || stimulus_grid[g+q*G]>=NI[q] )
                        mexErrMsgTxt("Invalid index");
                }
            }
        }
    }
    
    B = 0; /* number of time bins */
    
    if (nrhs>10) {
        /* CHECK DIMENSIONALITY OF TEST (DECODING) SPIKE TIMESTAMPS */
        if ( mxGetNumberOfDimensions(prhs[10])!=2 )
            mexErrMsgTxt("Timestamp input argument needs to be a matrix");
        timestamp = mxGetPr( prhs[10] );
        /* CHECK SIZE OF TEST (DECODING) SPIKE TIMESTAMPS */        
        if ( mxGetM( prhs[10] )!=M || mxGetN( prhs[10] )!=1 )
            mexErrMsgTxt("Incompatible size of timestamp input argument");
    }
    
    if (nrhs>11) {
        /* CHECK DIMENSIONALITY AND SIZE OF TIME BINS ARGUMENT */
        if ( mxGetNumberOfDimensions(prhs[11])!=2 || mxGetN(prhs[11])!=2)
            mexErrMsgTxt("Bins input argument needs to be a Bx2 matrix");
        B = mxGetM( prhs[11] ); /* number of time bins */
        bins = mxGetPr( prhs[11] );
    }
    
    cutoff *= cutoff; /* transform gaussian kernel cut-off to variance*/
    
    /* COMPUTE CUT-OFFS FOR VON MISES KERNELS */
    /* AND COUNT NUMBER OF DIMENSIONS WITH GAUSSIAN/EPANECHNIKOV/KRONECKER/VONMISES KERNELS */
    stimulus_vonmises = (double*) mxCalloc( Q, sizeof(double) );
    response_vonmises = (double*) mxCalloc( D, sizeof(double) );
    
    
    argin[0] = mxCreateDoubleScalar(0);
    argin[1] = mxCreateDoubleScalar(0);
    pargin1 = mxGetPr(argin[0]);
    pargin2 = mxGetPr(argin[1]);

    for (q=0; q<Q; q++) {
        if (stimulus_kernel[q]==0) {
            ngauss++;
        } else if (stimulus_kernel[q]==1) {
            nepa++;
        } else if (stimulus_kernel[q]==2) {
            nmises++;
            pargin2[0] = stimulus_bandwidth[q];
            mexCallMATLAB(1, &argout, 2, argin, "besseli");
            stimulus_vonmises[q] = acos( log( vm_cutoff * 2*pi * mxGetScalar(argout) ) / stimulus_bandwidth[q] );
            scaling_factor /= mxGetScalar(argout); 
        } else {
            nkron++;
        }
    }
    for (d=0; d<D; d++) {
        if (response_kernel[d]==0) {
            ngauss++;
        } else if (response_kernel[d]==1) {
            nepa++;
        } else if (response_kernel[d]==2) {
            nmises++;
            pargin2[0] = response_bandwidth[d];
            mexCallMATLAB(1, &argout, 2, argin, "besseli");
            response_vonmises[d] = acos( log( vm_cutoff * 2*pi * mxGetScalar(argout) ) / response_bandwidth[d] );
            scaling_factor /= mxGetScalar(argout);
        } else {
            nkron++;
        }
    }
          
    /* COMPUTE SCALING FACTOR */
              
    if (ngauss>0)
        scaling_factor *= pow(2*pi,-((double)ngauss)/2);
    if (nepa>0) {
        /* compute volume of hypersphere */
        pargin1[0] = ((double)nepa)/2 + 1; 
        mexCallMATLAB(1, &argout, 1, argin, "gamma" );
        v = pow(pi,0.5*(double)(nepa))/mxGetScalar(argout);
        scaling_factor *= 0.5*(double)(nepa+2)/v;
    }
    if (nmises>0) {
        scaling_factor /= pow(2*pi,(double)nmises);
    }
    if (nkron>0) {
        /* compute volume of hypersphere */
        pargin1[0] = ((double)nkron)/2 + 1; 
        mexCallMATLAB(1, &argout, 1, argin, "gamma" );
        v = pow(pi,((double)nkron)/2)/mxGetScalar(argout);
        scaling_factor /= v; 
    }
      
    /* ALLOCATE TEMPORARY ARRAYS AND OUTPUT ARRAYS */
    acc_g_gauss  = (double*) mxCalloc( G, sizeof(double) );
    acc_g_epa  = (double*) mxCalloc( G, sizeof(double) );
    acc_g_delta  = (double*) mxCalloc( G, sizeof(double) );
    acc_g_vm  = (double*) mxCalloc( G, sizeof(double) );
    skip_g = (double*) mxCalloc( G, sizeof(double) );
    
    if (B==0) {
        out = mxCreateDoubleMatrix( M, G, mxREAL );
        z = mxGetPr( out );
    } else {
        if (D==0) {
            z = (double*) mxCalloc( G, sizeof(double) );
        } else {
            z = (double*) mxCalloc( M*G, sizeof(double) );
        }
        out = mxCreateDoubleMatrix( B, G, mxREAL );
        pout = mxGetPr( out );
        
        out2 = mxCreateDoubleMatrix( B, 1, mxREAL );
        pout2 = mxGetPr( out2 );
    }
    
    loopM = sizeM = M;
    if (D==0) {
        loopM = 1;
        if (B>0)
            sizeM = 1;
    }
    
    /* COMPUTE KDE */
    
    /* LOOP THROUGH SOURCE (ENCODING) SPIKES */
    for ( n=0; n<N; n++ ) {
        
        /* LOOP THROUGH STIMULUS GRID */
        for ( g=0; g<G; g++ ) {
            
            /* INITIALIZE ACCUMULATORS */
            acc_g_gauss[g] = 0;
            acc_g_epa[g] = 0;
            acc_g_delta[g] = 0;
            acc_g_vm[g] = 0;
            skip_g[g] = 0;
            
            /* INITIALIZE INDICES */
            idx1 = g;
            idx2 = n;
            
            /* LOOP THROUGH STIMULUS DIMENSIONS */
            for ( q=0; q<Q; q++ ) {
                
                /* GAUSSIAN KERNEL */
                if (stimulus_kernel[q]==0) {
                    if (use_distance_lookup[q]) {
                        tmp = distance[q][ ((int) stimulus_grid[idx1])*NI[q] + (int)stimulus[idx2] ];
                    } else {
                        tmp = (stimulus_grid[idx1]-stimulus[idx2]);
                    }

                    acc_g_gauss[g] += tmp*tmp;
                    
                    if (acc_g_gauss[g]>cutoff) {
                        skip_g[g] = 1;
                        break;
                    }
                /* EPANECHNIKOV KERNEL */    
                } else if (stimulus_kernel[q]==1) {
                    if (use_distance_lookup[q]) {
                        tmp = distance[q][ ((int) stimulus_grid[idx1])*NI[q] + (int)stimulus[idx2] ];
                    } else {
                        tmp = (stimulus_grid[idx1]-stimulus[idx2]);
                    }

                    acc_g_epa[g]+=tmp*tmp;

                    if (acc_g_epa[g]>1) {
                        skip_g[g] = 1;
                        break;
                    }
                /* VON MISES KERNEL */    
                } else if (stimulus_kernel[q]==2) {
                    if (use_distance_lookup[q]) {
                        tmp = distance[q][ ((int) stimulus_grid[idx1])*NI[q] + (int)stimulus[idx2] ];
                    } else {
                        tmp = fabs(stimulus_grid[idx1]-stimulus[idx2]);
                    }

                    if ( tmp<stimulus_vonmises[q] || tmp>(2*pi-stimulus_vonmises[q]) ) {
                        
                        acc_g_vm[g] += stimulus_bandwidth[q] * cos(tmp);

                    } else {
                        skip_g[g] = 1;
                        break;
                    }
                        
                /* KRONECKER KERNEL */
                } else {
                    if (use_distance_lookup[q]) {
                        tmp = distance[q][ ((int) stimulus_grid[idx1])*NI[q] + (int)stimulus[idx2] ];
                    } else {
                        tmp = (stimulus_grid[idx1]-stimulus[idx2]);
                    }

                    acc_g_delta[g] += tmp*tmp;

                    if (acc_g_delta[g]>1) {
                        skip_g[g] = 1;
                        break;
                    }
                }
                
                /* UPDATE INDICES */
                idx1 += G;
                idx2 += N;

            }
            
        }
        
        /* LOOP THROUGH TEST (DECODING) SPIKES */
        for ( m=0; m<loopM; m++ ) {
            
            /* INITIALIZE ACCUMULATORS */
            acc_a_gauss = 0;
            acc_a_epa   = 0;
            acc_a_delta = 0;
            acc_a_vm    = 0;
            
            /* INTIALIZE INDICES */
            idx1 = m;
            idx2 = n;
            
            /* LOOP THROUGH RESPONSE DIMENSIONS */
            for ( d=0; d<D; d++ ) {
                
                /* GAUSSIAN KERNEL */
                if (response_kernel[d]==0) {

                    tmp = (test_response[idx1]-response[idx2]);
                    acc_a_gauss += tmp*tmp;
                    
                    if (acc_a_gauss>cutoff) {
                        goto nextm;
                    }
                /* EPANECHNIKOV KERNEL */    
                } else if (response_kernel[d]==1) {

                    tmp = (test_response[idx1]-response[idx2]);
                    acc_a_epa += tmp*tmp;

                    if (acc_a_epa>1) {
                        goto nextm;
                    }
                /* VON MISES KERNEL */    
                } else if (response_kernel[d]==2) {

                    tmp = fabs(test_response[idx1]-response[idx2]);

                    if ( tmp<response_vonmises[d] || tmp>(2*pi-response_vonmises[d]) ) {
                        acc_a_vm += response_bandwidth[d] * cos(tmp);
                    } else {
                        goto nextm;
                    }
                /* KRONECKER KERNEL */
                } else {

                    tmp = (test_response[idx1]-response[idx2]);
                    acc_a_delta += tmp*tmp;

                    if (acc_a_delta>1) {
                        goto nextm;
                    }
                }
                
                /* UPDATE INDICES */
                idx1 += sizeM;
                idx2 += N;
                
            }
            
            /* LOOP THROUGH STIMULUS GRID */
            for ( g=0; g<G; g++ ) {
                
                if (skip_g[g] || acc_g_gauss[g]+acc_a_gauss>cutoff || acc_g_epa[g]+acc_a_epa>1 || acc_g_delta[g]+acc_a_delta>1)
                    continue;
                
                z[m+g*sizeM] += exp( -0.5*(acc_g_gauss[g]+acc_a_gauss) + acc_g_vm[g] + acc_a_vm ) * (1-acc_g_epa[g]-acc_a_epa);
                
            }
            
            nextm:
                ;
        
        }
        
    }
    
    mxFree(acc_g_gauss);
    mxFree(acc_g_epa);
    mxFree(acc_g_delta);
    mxFree(acc_g_vm);
    mxFree(skip_g);
    mxFree(stimulus_vonmises);
    mxFree(response_vonmises);
    

    if (argout!=NULL)
        mxDestroyArray(argout);
    
    mxDestroyArray(argin[0]);
    mxDestroyArray(argin[1]);
    
    
    /* compute log */
    c1 = log(scaling_factor) - log((double)N);
    if (B==0 && D==0) {
        for (g=0;g<G;g++)
            z[g*sizeM]=log( z[g*sizeM] + offset[g]*(double)N/scaling_factor ) + c1;
    } else {
        for (g=0; g<G; g++) {
            idx = g*loopM;
            c2 = offset[g]*(double)N/scaling_factor;
            for (m=0; m<loopM ; m++ )
                z[m+idx] = log( z[m+idx] + c2) + c1;
        }
    }
    
    if (D==0 && B==0) { /* copy */
        for (g=0; g<G; g++) {
            idx = g*sizeM;
            for (m=1; m<sizeM ; m++ )
                z[m+idx] = z[idx];
        }
    }
    
    if (B>0) {
        
        next_idx = 0;
    
        for (b=0; b<B; b++) {
     
            while (next_idx<M && (timestamp[next_idx]<bins[b]))
                next_idx++;
        
            idx = next_idx;
            while (idx<M && (timestamp[idx]<bins[b+B])) {
            
                if (D>0) {
                    for (g=0; g<G; g++)
                        pout[b+g*B] += z[idx+g*M];
                }
            
                pout2[b]++;
                
                idx++;
            }
        
            if (D==0) {
                for (g=0; g<G; g++) {
                    pout[b+g*B] = pout2[b] * z[g*sizeM];
                }
            }
            
        }
        
        mxFree(z);
        
    }
    
    plhs[0] = out;
    plhs[1] = out2;
    
}