void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
  mxArray **analyticFnParam;
  mxArray *aRandVec, *aRandVecN;
  mxArray *aRandParam;
  double *pRandParam, *randU, *randN;

  mxArray *pointsM, *weightsM, *indicesM;
  double *points, *weights;
  BallTree::index* indices;

  unsigned int i;
  unsigned int Niter,Ndens,Ndim,Np;
  
  /*********************************************************************
  ** Verify arguments and initialize variables
  *********************************************************************/

  if (nrhs < 3)
    mexErrMsgTxt("Takes 3-5 input arguments");
  if (nlhs != 2)
    mexErrMsgTxt("Outputs 2 results");

  Ndens = mxGetN(prhs[0]);               // get # of densities

  /*********************************************************************
  ** Transform Matlab cell arrays into struct NPD representation
  *********************************************************************/

  BallTreeDensity *trees = new BallTreeDensity[Ndens];
  bool allGaussians = true;
  for (i=0; i < Ndens; i++) {
    trees[i] = BallTreeDensity( mxGetCell(prhs[0],i) );
    if (trees[i].getType() != BallTreeDensity::Gaussian) allGaussians = false;
  }
  if (!allGaussians)
    mexErrMsgTxt("Sorry -- only Gaussian kernels supported");

  Ndim  = trees[0].Ndim();          //  # of dimensions  
  Np    = (unsigned long) mxGetScalar(prhs[1]);     //  # of points to sample
  Niter = (unsigned int)  mxGetScalar(prhs[2]);     //  # of gibbs iterations

  if ((nrhs < 5) || (mxGetN(prhs[3]) == 0)) {   // load analytic function
    analyticFnParam = NULL;                     //   params if required
  }
  else {
    analyticFnParam = (mxArray**) mxMalloc(3*sizeof(mxArray*));
    analyticFnParam[0] = (mxArray*) prhs[3];
    analyticFnParam[1] = (mxArray*) prhs[4];
  }

  pointsM = plhs[0] = mxCreateDoubleMatrix(Ndim, Np, mxREAL);   // set up matlab output
  points  = (double*) mxGetData(plhs[0]);
//  plhs[1] = mxCreateDoubleMatrix(1, Np, mxREAL);
//  weights = (double*) mxGetData(plhs[1]);
  plhs[1] = mxCreateNumericMatrix(Ndens, Np, mxUINT32_CLASS, mxREAL);
  indices = (BallTree::index*) mxGetData(plhs[1]);

  unsigned long maxNp = Np;             // largest # of particles we deal with
  for (unsigned int j=0; j<Ndens; j++)  // compute Max Np over all densities
    if (maxNp < trees[j].Npts()) maxNp = trees[j].Npts();
  unsigned int Nlevels = (unsigned int) (log((double)maxNp)/log((double)2))+1;  // how many levels to a balanced binary tree?

  // Generate enough random numbers to get us through the rest of this
  aRandParam = mxCreateDoubleMatrix(1, 2, mxREAL);
  pRandParam = mxGetPr(aRandParam);
  pRandParam[0] = 1;  pRandParam[1] = Np*Ndens*(Niter+1)*Nlevels;
  mexCallMATLAB(1, &aRandVec, 1, &aRandParam, "rand");   randU = mxGetPr(aRandVec);
  pRandParam[0] = 1;  pRandParam[1] = Ndim*Np*(Niter+1)*Nlevels;
  mexCallMATLAB(1, &aRandVecN, 1, &aRandParam, "randn"); randN = mxGetPr(aRandVecN);
  mxDestroyArray(aRandParam);

  // Params:  Ndens, trees, points, weights, indices, randomU, randomN
  gibbs2(Ndens,trees,Np,Niter,points,indices, randU,randN);

  delete[] trees;

  if (analyticFnParam != NULL)
    mxFree(analyticFnParam);

  mxDestroyArray(aRandVec);
  mxDestroyArray(aRandVecN);
}
Beispiel #2
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;

    } 
}
Beispiel #3
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;
  }
Beispiel #4
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);
    }
}
Beispiel #5
0
/* The matlab mex function */
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) {
    /* Vertex list input */
    double *V;
    /* Neighbour list input */
    const mxArray *Ne;
    mxArray *PneigMatlab;
    mwSize *PneigDims;
    int PneigLenght=0;
    
    /* Outputs */
    double *ET_table; /* Edge tangents table */
    double *EV_table; /* Edge velocity */
    double *ETV_index; /* Edge tangents/velocity index for tables */
    
    double Ea, Eb, Ec, s, h, x, Tb3D_length, Vv;
    double Np[3], Ns[3], Tb[3], Pm[3], X3[3], Y3[3], Tb3D[3];
    double *Pn, *Pnop, *Pneig;
    /* Current vertex */
    double P[3]={0,0,0};
    
    /* Table Size */
    mwSize table_Dims[2]={1,3};
    
    /* Number of vertices */
    const mwSize *VertexDims;
    int VertexN=0;
    
    /* Number of indices */
    int ETV_num=0;
    
    /* Neighbour indices */
    double neg;
    int neg1, neg2;
    
    /* Loop variables */
    int i, j, k;
    
    /* Check for proper number of arguments. */
    if(nrhs!=2) {
        mexErrMsgTxt("2 inputs are required.");
    } else if(nlhs!=3) {
        mexErrMsgTxt("3 output is required");
    }
    
    
    /* Connect Inputs */
    V=(double *)mxGetPr(prhs[0]);
    Ne=prhs[1];
    
    /* Get number of VertexN */
    VertexDims = mxGetDimensions(prhs[0]);
    VertexN=VertexDims[0];
    
    
    /* Reserve memory */
    table_Dims[0]=VertexN*6; table_Dims[1]=3;
    plhs[0]= mxCreateNumericArray(2, table_Dims, mxDOUBLE_CLASS, mxREAL);
    table_Dims[0]=VertexN*6; table_Dims[1]=1;
    plhs[1]= mxCreateNumericArray(2, table_Dims, mxDOUBLE_CLASS, mxREAL);
    table_Dims[0]=VertexN*6; table_Dims[1]=2;
    plhs[2] = mxCreateNumericArray(2, table_Dims, mxDOUBLE_CLASS, mxREAL);
    
    /* Connect Outputs */
    ET_table=(double *)mxGetPr(plhs[0]);
    EV_table=(double *)mxGetPr(plhs[1]);
    ETV_index=(double *)mxGetPr(plhs[2]);
    
    
    
    Pn= (double *)malloc(VertexN*3*sizeof(double));
    Pnop=(double *) malloc(VertexN*3*sizeof(double));
    

    for (i=0; i<VertexN; i++) {
        P[0]=V[i]; P[1]=V[i+VertexN]; P[2]=V[i+VertexN*2];
        PneigMatlab=mxGetCell(Ne, i);
        if( PneigMatlab == NULL)
        {
            PneigLenght=-1;
        }
        else
        {
            PneigDims=(mwSize *)mxGetDimensions(PneigMatlab);
            PneigLenght=(PneigDims[0]*PneigDims[1]);
            Pneig=(double *)mxGetPr(PneigMatlab);
        }
        /* Find the opposite vertex of each neigbourh vertex. */
        /* incase of odd number of neigbourhs interpolate the opposite neigbourh */
        if((PneigLenght%2)==0) {
            for (k=0; k<PneigLenght; k++) {
                neg =k+((double)PneigLenght)/2;
                neg1=(int)floor(neg);
                if(neg1>(PneigLenght-1)) { neg1=neg1-PneigLenght; }
                Pn[k]          =V[(int)Pneig[k]-1];
                Pn[k+VertexN]  =V[(int)Pneig[k]-1+VertexN];
                Pn[k+VertexN*2]=V[(int)Pneig[k]-1+VertexN*2];
                
                Pnop[k]          =V[(int)Pneig[neg1]-1];
                Pnop[k+VertexN]  =V[(int)Pneig[neg1]-1+VertexN];
                Pnop[k+VertexN*2]=V[(int)Pneig[neg1]-1+VertexN*2];
            }
        }
        else {
            for (k=0; k<PneigLenght; k++) {
                neg=(double)k+((double)PneigLenght)*0.5;
                neg1=(int)floor(neg); neg2=(int)ceil(neg);
                if(neg1>(PneigLenght-1)) { neg1=neg1-PneigLenght; }
                if(neg2>(PneigLenght-1)) { neg2=neg2-PneigLenght; }
                Pn[k]          =V[(int)Pneig[k]-1];
                Pn[k+VertexN]  =V[(int)Pneig[k]-1+VertexN];
                Pn[k+VertexN*2]=V[(int)Pneig[k]-1+VertexN*2];
                
                Pnop[k]          =(V[(int)Pneig[neg1]-1]           + V[(int)Pneig[neg2]-1])/2;
                Pnop[k+VertexN]  =(V[(int)Pneig[neg1]-1+VertexN]   + V[(int)Pneig[neg2]-1+VertexN])/2;
                Pnop[k+VertexN*2]=(V[(int)Pneig[neg1]-1+VertexN*2] + V[(int)Pneig[neg2]-1+VertexN*2])/2;
            }
        }
        
        for(j=0;j<PneigLenght; j++) {
            /* Calculate length edges of face */
            Ec= sqrt(pow2(Pn[j]-P[0])   +pow2(Pn[j+VertexN]-P[1])   +pow2(Pn[j+VertexN*2]-P[2]))+1e-14;
            Eb= sqrt(pow2(Pnop[j]-P[0]) +pow2(Pnop[j+VertexN]-P[1]) +pow2(Pnop[j+VertexN*2]-P[2]))+1e-14;
            Ea= sqrt(pow2(Pn[j]-Pnop[j])+pow2(Pn[j+VertexN]-Pnop[j+VertexN]) +pow2(Pn[j+VertexN*2]-Pnop[j+VertexN*2]))+1e-14;
           
            /* Calculate face surface area */
            s = ((Ea+Eb+Ec)/2);
            h = (2/Ea)*sqrt(s*(s-Ea)*(s-Eb)*(s-Ec))+1e-14;
            x = (pow2(Ea)-pow2(Eb)+pow2(Ec))/(2*Ea);
            
            /* Calculate tangent of 2D triangle */
            Np[0]=-h / sqrt(pow2(-h)+pow2(x));   Np[1]= x / sqrt(pow2(-h)+pow2(x));
            Ns[0]=h / sqrt(pow2(h)+pow2(Ea-x));  Ns[1]=(Ea-x) / sqrt(pow2(h)+pow2(Ea-x));
            Tb[0]= Np[1]+Ns[1] ; Tb[1]=-(Np[0]+Ns[0]);
            
            /* Back to 3D coordinates */
            Pm[0]=(Pn[j]*x+Pnop[j]*(Ea-x))/Ea;
            Pm[1]=(Pn[j+VertexN]*x+Pnop[j+VertexN]*(Ea-x))/Ea;
            Pm[2]=(Pn[j+VertexN*2]*x+Pnop[j+VertexN*2]*(Ea-x))/Ea;
            X3[0]=(Pn[j]-Pnop[j])/Ea;
            X3[1]=(Pn[j+VertexN]-Pnop[j+VertexN])/Ea;
            X3[2]=(Pn[j+VertexN*2]-Pnop[j+VertexN*2])/Ea;
            Y3[0]=(P[0]-Pm[0])/h; 
            Y3[1]=(P[1]-Pm[1])/h;
            Y3[2]=(P[2]-Pm[2])/h;
            
            /* 2D tangent to 3D tangent */
            Tb3D[0]=(X3[0]*Tb[0]+Y3[0]*Tb[1]); 
            Tb3D[1]=(X3[1]*Tb[0]+Y3[1]*Tb[1]); 
            Tb3D[2]=(X3[2]*Tb[0]+Y3[2]*Tb[1]); 
            Tb3D_length=sqrt(pow2(Tb3D[0])+pow2(Tb3D[1])+pow2(Tb3D[2]))+1e-14;
            Tb3D[0]=Tb3D[0]/Tb3D_length;
            Tb3D[1]=Tb3D[1]/Tb3D_length;
            Tb3D[2]=Tb3D[2]/Tb3D_length;
            
            /* Edge Velocity */
            Vv=0.5*(Ec+0.5*Ea);
          
            /* Store the data */
            ETV_index[ETV_num]=i+1;
          
            ETV_index[ETV_num+table_Dims[0]]=Pneig[j];
            
            ET_table[ETV_num]=Tb3D[0];
            ET_table[ETV_num+table_Dims[0]]=Tb3D[1];
            ET_table[ETV_num+2*table_Dims[0]]=Tb3D[2];
            EV_table[ETV_num]=Vv;
            ETV_num++;
            
            
        }

         
    }

    
    /* Remove temporary memory */
    free(Pn);
    free(Pnop);
    
}
void LTFAT_NAME(ltfatMexFnc)( int UNUSED(nlhs), mxArray *plhs[],
                              int UNUSED(nrhs), const mxArray *prhs[] )
{

    static int atExitFncRegistered = 0;
    if(!atExitFncRegistered)
    {
        LTFAT_NAME(ltfatMexAtExit)(LTFAT_NAME(fftblMexAtExitFnc));
        atExitFncRegistered = 1;
    }

    const mxArray* mxF = prhs[0];
    const mxArray* mxG = prhs[1];
    double* foffDouble = (double*) mxGetData(prhs[2]);
    double* a = (double*) mxGetData(prhs[3]);
    double* realonlyDouble = (double*) mxGetData(prhs[4]);

    // input data length
    mwSize L = mxGetM(mxF);
    // number of channels
    mwSize W = mxGetN(mxF);
    // filter number
    mwSize M = mxGetNumberOfElements(mxG);

    //
    mwSize acols = mxGetN(prhs[3]);

    double afrac[M];
    memcpy(afrac,a,M*sizeof*a);
    if(acols>1)
    {
        for(mwIndex m=0; m<M; m++)
        {
            afrac[m] = afrac[m]/a[M+m];
        }
    }

    // output lengths
    mwSize outLen[M];
    // Frequency offsets
    mwSignedIndex foff[M];
    // realonly
    int realonly[M];

    // POINTER TO THE INPUT
    LTFAT_COMPLEX* FPtr = mxGetData(prhs[0]);

    // POINTER TO THE FILTERS
    const LTFAT_COMPLEX* GPtrs[M];
    // filter lengths
    mwSize Gl[M];
    // POINTER TO OUTPUTS
    LTFAT_COMPLEX* cPtrs[M]; // C99 feature

    plhs[0] = mxCreateCellMatrix(M, 1);

    if(M!=LTFAT_NAME(oldM) || W != LTFAT_NAME(oldW))
    {
        LTFAT_NAME(fftblMexAtExitFnc)();
        LTFAT_NAME(oldM) = M;
        LTFAT_NAME(oldW) = W;
        LTFAT_NAME(oldLc) = ltfat_calloc(M,sizeof(mwSize));
        LTFAT_NAME(oldPlans) =  ltfat_calloc(M,sizeof*LTFAT_NAME(oldPlans));
    }

    for(mwIndex m=0; m<M; ++m)
    {
        foff[m] = (mwSignedIndex) foffDouble[m];
        realonly[m] = (realonlyDouble[m]>1e-3);
        outLen[m] = (mwSize) floor( L/afrac[m] +0.5);
        GPtrs[m] = mxGetData(mxGetCell(mxG, m));
        Gl[m] = mxGetNumberOfElements(mxGetCell(mxG, m));
        mxSetCell(plhs[0], m, ltfatCreateMatrix(outLen[m], W,
                                  LTFAT_MX_CLASSID,mxCOMPLEX));
        cPtrs[m] = mxGetData(mxGetCell(plhs[0],m));

        if(LTFAT_NAME(oldLc)[m]!=outLen[m])
        {
            LTFAT_NAME(oldLc)[m] = outLen[m];
            LTFAT_NAME(convsub_fftbl_plan) ptmp =
            LTFAT_NAME(convsub_fftbl_init)( L, Gl[m], W, afrac[m], cPtrs[m]);

            if(LTFAT_NAME(oldPlans)[m]!=0)
            {
                 LTFAT_NAME(convsub_fftbl_done)(LTFAT_NAME(oldPlans)[m]);
            }
            LTFAT_NAME(oldPlans)[m]=ptmp; 
        }

    }


    LTFAT_NAME(filterbank_fftbl_execute)( LTFAT_NAME(oldPlans),FPtr, GPtrs, M,
                                 foff, realonly, cPtrs);
}
Beispiel #7
0
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); 
     }
     mxFree(blknnz); 
     mxFree(cumblksize);
 return;
 }
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;
    
}
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]){
	int     i, j, NS, NZB, count, bdim, match, domain, bindex, sindex, nzCounts=0;
	int     *observed, *bsubv, *ssubv, *bir, *sir, *bjc, *sjc, *mask, *ssize, *bcumprod, *scumprod;
	double  *pDomain, *pSize, *bpr, *spr;
	mxArray *pTemp;

	pTemp = mxGetField(prhs[0], 0, "CPT");
	bpr = mxGetPr(pTemp);
	bir = mxGetIr(pTemp);
	bjc = mxGetJc(pTemp);
	NZB = bjc[1];
	pTemp = mxGetField(prhs[0], 0, "sizes");
	pSize = mxGetPr(pTemp);

	pDomain = mxGetPr(prhs[1]);
	bdim = mxGetNumberOfElements(prhs[1]);

	mask = malloc(bdim * sizeof(int));
	ssize = malloc(bdim * sizeof(int));
	observed = malloc(bdim * sizeof(int));

	for(i=0; i<bdim; i++){
		ssize[i] = (int)pSize[i];
	}

	count = 0;
	for(i=0; i<bdim; i++){
		domain = (int)pDomain[i] - 1;
		pTemp = mxGetCell(prhs[2], domain);
		if(pTemp){
			mask[count] = i;
			ssize[i] = 1;
			observed[count] = (int)mxGetScalar(pTemp) - 1;
			count++;
		}
	}

	if(count == 0){
		pTemp = mxGetField(prhs[0], 0, "CPT");
		plhs[0] = mxDuplicateArray(pTemp);
		free(mask);
		free(ssize);
		free(observed);
		return;
	}

	bsubv = malloc(bdim * sizeof(int));
	ssubv = malloc(count * sizeof(int));
	bcumprod = malloc(bdim * sizeof(int));
	scumprod = malloc(bdim * sizeof(int));

	NS = 1;
	for(i=0; i<bdim; i++){
		NS *= ssize[i];
	}

	plhs[0] = mxCreateSparse(NS, 1, NS, mxREAL);
	spr = mxGetPr(plhs[0]);
	sir = mxGetIr(plhs[0]);
	sjc = mxGetJc(plhs[0]);
	sjc[0] = 0;
	sjc[1] = NS;

	bcumprod[0] = 1;
	scumprod[0] = 1;
	for(i=0; i<bdim-1; i++){
		bcumprod[i+1] = bcumprod[i] * (int)pSize[i];
		scumprod[i+1] = scumprod[i] * ssize[i];
	}

	nzCounts = 0;
	for(i=0; i<NZB; i++){
		bindex = bir[i];
		ind_subv(bindex, bcumprod, bdim, bsubv);
		for(j=0; j<count; j++){
			ssubv[j] = bsubv[mask[j]];
		}
		match = 1;
		for(j=0; j<count; j++){
			if((ssubv[j]) != observed[j]){
				match = 0;
				break;
			}
		}
		if(match){
			spr[nzCounts] = bpr[i];
			sindex = subv_ind(bdim, scumprod, bsubv);
			sir[nzCounts] = sindex;
			nzCounts++;
		}
	}

	reset_nzmax(plhs[0], NS, nzCounts);
	free(mask);
	free(ssize);
	free(observed);
	free(bsubv);
	free(ssubv);
	free(bcumprod);
	free(scumprod);
}
// Main function ===============================================================
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
    const mxArray *A, *AC, *B, *BC;
    int           nA, nB, iA, iB, ASlen, *BSlenp, *BSlen, Rlen,
                  CaseSensitive = 1;
    double        *RA, *RAp, *RB, *RBp;
    unsigned char **BS, **BSp, **BSEnd, *AS, *CaseArg;

    // Check for proper number of arguments:
    if (nrhs < 2 || nrhs > 3) {
        mexErrMsgTxt("*** CStrAinBP[mex]: 2 or 3 inputs required.");
    }
    if (nlhs > 2) {
        mexErrMsgTxt("*** CStrAinBP[mex]: 1 or 2 outputs allowed.");
    }

    // Set flag according to optional 3rd input:
    if (nrhs == 3) {
        // Compare first character of 3rd argument:
        if (mxGetNumberOfElements(prhs[2]) > 0) {
            CaseArg = (unsigned char *)mxGetData(prhs[2]);
            if (*CaseArg == 'i' || *CaseArg == 'I') {
                CaseSensitive = 0;
            }
        }
    }

    // Create a pointer to the input arrays:
    A = prhs[0];
    B = prhs[1];

    // Check that inputs are cells:
    if (!mxIsCell(A) || !mxIsCell(B)) {
        mexErrMsgTxt("*** CStrAinBP[mex]: Inputs must be cells.");
    }

    // Get number of dimensions of the input string and cell:
    nA = mxGetNumberOfElements(A);
    nB = mxGetNumberOfElements(B);

    // Create container for output arguments:
    RA = (double *)mxMalloc(nA * sizeof(double));
    RB = (double *)mxMalloc(nA * sizeof(double));

    // Make list of pointers to elements of B and their length:
    BSlen = (int *) mxMalloc(nB * sizeof(int));
    BS    = (unsigned char **)mxMalloc(nB * sizeof(unsigned char *));
    BSEnd = BS + nB;
    for (iB = 0, BSp = BS, BSlenp = BSlen; iB < nB; iB++) {
        if ((BC = mxGetCell(B, iB)) == NULL) {  // Uninitialized cell element:
            mexErrMsgTxt("*** CStrAinBP[mex]: Element of B is NULL.");
        }

        if (!mxIsChar(BC)) {
            mexErrMsgTxt("*** CStrAinBP[mex]: Element of B is no string.");
        }

        *BSlenp++ = mxGetNumberOfElements(BC);
        *BSp++    = (unsigned char *)mxGetData(BC);
    }  // end for iB

    // Pointers to list of strings:
    RAp = RA;
    RBp = RB;

    if (CaseSensitive) {  // -----------------------------------------------------
        for (iA = 0; iA < nA; iA++) {  // Loop over all strings of A:
            if ((AC = mxGetCell(A, iA)) == NULL) {  // Uninitialized cell element:
                mexErrMsgTxt("*** CStrAinBP[mex]: Element of A is NULL.");
            }

            if (!mxIsChar(AC)) {         // Check if cell element is a string:
                mexErrMsgTxt("*** CStrAinBP[mex]: Element of A is no string.");
            }

            AS     = (unsigned char *)mxGetData(AC);
            ASlen  = mxGetNumberOfElements(AC);
            BSlenp = BSlen;  // Pointer to list of lengths of B's strings

            // Loop over pointers to strings of B:
            for (BSp = BS; BSp < BSEnd; BSp++) {
                if (ASlen == *BSlenp++) {     // Cheap comparison of length
                    if (memcmp(AS, *BSp, ASlen * sizeof(mxChar)) == 0) {
                        *RAp++ = (double) (iA + 1);
                        *RBp++ = (double) (BSp - BS + 1);
                        break;  // Just take first occurrence in B
                    }
                }
            }   // end for BSp
        }  // end for iA

    } else {  // Not case-sensitive: ---------------------------------------------
        // Same method except for memcmp -> my_memicmpW:
        for (iA = 0; iA < nA; iA++) {  // Loop over all strings of A:
            if ((AC = mxGetCell(A, iA)) == NULL) {  // Uninitialized cell element:
                mexErrMsgTxt("*** CStrAinBP[mex]: Element of A is NULL.");
            }

            if (!mxIsChar(AC)) {         // Check if cell element is a string:
                mexErrMsgTxt("*** CStrAinBP[mex]: Element of A is no string.");
            }

            AS     = (unsigned char *)mxGetData(AC);
            ASlen  = mxGetNumberOfElements(AC);
            BSlenp = BSlen;  // Pointer to list of lengths of B's strings

            // Loop over pointers to strings of B:
            for (BSp = BS; BSp < BSEnd; BSp++) {
                if (ASlen == *BSlenp++) {     // Cheap comparison of length
                    if (my_memicmpW(AS, *BSp, ASlen) == 0) {
                        *RAp++ = (double) (iA + 1);
                        *RBp++ = (double) (BSp - BS + 1);
                        break;  // Just take first occurrence in B
                    }
                }
            }   // end for BSp
        }  // end for iA

    }

    // Create output arguments, [0 x 0] for empty arrays:
    Rlen    = (int) (RAp - RA);  // Number of found occurrences
    plhs[0] = mxCreateDoubleMatrix(Rlen ? 1 : 0, Rlen, mxREAL);
    memcpy(mxGetPr(plhs[0]), RA, Rlen * sizeof(double));

    if (nlhs == 2) {
        plhs[1] = mxCreateDoubleMatrix(Rlen ? 1 : 0, Rlen, mxREAL);
        memcpy(mxGetPr(plhs[1]), RB, Rlen * sizeof(double));
    }

    // Free memory for indices, strings and strings lengths:
    mxFree(RA);
    mxFree(RB);
    mxFree(BS);
    mxFree(BSlen);

    return;
}
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    
    // input arguments
    GLuint programID = 0;
    size_t nBuffers = 0;
    size_t nNames = 0;
    size_t nOffsets = 0;
    size_t nIsNormalized = 0;
    
    // input data
    int i = 0;
    GLuint attribIndex = 1;
    mxArray* mxAttribName = NULL;
    char* attribName = NULL;
    double* mxOffsetData = NULL;
    double* mxIsNormalizedData = NULL;
    
    // VBO data
    GLuint bufferID = 0;
    size_t bytesPerElement = 0;
    size_t byteOffset = 0;
    GLint elementsPerVertex = 0;
    GLsizei elementStride = 0;
    GLsizei byteStride = 0;
    mxArray* mxData = NULL;
    GLenum glType = GL_FLOAT;
    GLboolean isNormalized = GL_FALSE;
    
    // status
    GLint maxAttributes = -1;
    size_t nSelected = 0;
    int status = 0;
    GLenum error = GL_NO_ERROR;
    
    dotsMglClearGLErrors();
    
    // empty input means disable all generic vertex attributes, exept 0
    if (nrhs < 1 || mxIsEmpty(prhs[0])) {
        glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxAttributes);
        if (maxAttributes > 0) {
            for (i=1; i<maxAttributes; i++)
                glDisableVertexAttribArray(i);
        }
        plhs[0] = mxCreateDoubleScalar(0);
        return;
    }
    
    // check input arguments
    if (nrhs < 2 || nrhs > 5
            || !mxIsStruct(prhs[0]) || mxIsEmpty(prhs[0])
            || !mxIsStruct(prhs[1]) || mxIsEmpty(prhs[1])) {
        plhs[0] = mxCreateDoubleScalar(-1);
        usageError("dotsMglSelectVertexAttributes");
        return;
    }
    
    // is this a shader program info struct?
    programID = (GLuint)dotsMglGetInfoScalar(prhs[0], 0, "programID", &status);
    if (status < 0) {
        plhs[0] = mxCreateDoubleScalar(-2);
        return;
    }
    
    // how many attribute buffers?
    nBuffers = mxGetNumberOfElements(prhs[1]);
    
    // how many attribute names?
    if (nrhs >= 3 && mxIsCell(prhs[2]) && !mxIsEmpty(prhs[2])) {
        nNames = mxGetNumberOfElements(prhs[2]);
        if (nBuffers != nNames) {
            mexPrintf("(dotsMglSelectVertexAttributes) Number of buffer names %d must match number of buffers %d.\n",
                    nNames, nBuffers);
            plhs[0] = mxCreateDoubleScalar(-3);
            return;
        }
    }
    
    // how many buffer offsets?
    if (nrhs >= 4 && mxIsDouble(prhs[3]) && !mxIsEmpty(prhs[3])) {
        nOffsets = mxGetNumberOfElements(prhs[3]);
        if (nBuffers != nOffsets) {
            mexPrintf("(dotsMglSelectVertexAttributes) Number of buffer offsets %d must match number of buffers %d.\n",
                    nOffsets, nBuffers);
            plhs[0] = mxCreateDoubleScalar(-4);
            return;
        }
        mxOffsetData = mxGetPr(prhs[3]);
    }
    
    // how many buffer normalize flags?
    if (nrhs >= 5 && mxIsDouble(prhs[4]) && !mxIsEmpty(prhs[4])) {
        nIsNormalized = mxGetNumberOfElements(prhs[4]);
        if (nBuffers != nIsNormalized) {
            mexPrintf("(dotsMglSelectVertexAttributes) Number of buffer normalize flags %d must match number of buffers %d.\n",
                    nIsNormalized, nBuffers);
            plhs[0] = mxCreateDoubleScalar(-5);
            return;
        }
        mxIsNormalizedData = mxGetPr(prhs[4]);
    }
    
    // iterate buffers to enable attributes
    for (i=0; i<nBuffers; i++) {
        
        // enable the next numbered attribute
        //  ignoring attribute 0
        attribIndex = i+1;
        glEnableVertexAttribArray(attribIndex);
        
        // assign a name to the numbered attribute?
        if (nNames > 0){
            mxAttribName = mxGetCell(prhs[2], i);
            attribName = mxArrayToString(mxAttribName);
            
            glBindAttribLocation(programID, attribIndex, (const GLchar*)attribName);
            if (attribName != NULL){
                mxFree(attribName);
                attribName = NULL;
            }
            
            error = glGetError();
            if(error != GL_NO_ERROR) {
                mexPrintf("(dotsMglSelectVertexAttributes) Error assigning name %s to vertex attribute %d.  glGetError()=%d\n",
                        attribName, attribIndex, error);
                continue;
            }
        }
        
        // VBO accounting
        bufferID = (GLuint)dotsMglGetInfoScalar(prhs[1], i, "bufferID", &status);
        if (status < 0) {
            mexPrintf("(dotsMglSelectVertexAttributes) %dth buffer info struct is invalid.\n",
                    i);
            continue;
        }
        
        // how are the VBO elements formatted?
        elementsPerVertex = (GLint)dotsMglGetInfoScalar(prhs[1], i, "elementsPerVertex", &status);
        elementStride = (GLsizei)dotsMglGetInfoScalar(prhs[1], i, "elementStride", &status);
        bytesPerElement = (size_t)dotsMglGetInfoScalar(prhs[1], i, "bytesPerElement", &status);
        byteStride = elementStride * bytesPerElement;
        mxData = mxGetField(prhs[1], i, "mxData");
        glType = dotsMglGetGLNumericType(mxData);
        
        // use an offset into the VBO?
        if (nOffsets > 0 && mxOffsetData != NULL)
            byteOffset = (size_t)mxOffsetData[i] * bytesPerElement;
        else
            byteOffset = 0;
        
        // normalize data in the VBO?
        if (nIsNormalized > 0 && mxIsNormalizedData != NULL)
            isNormalized = mxIsNormalizedData[i] ? GL_TRUE : GL_FALSE;
        else
            isNormalized = 0;
        
        // assign the VBO to this numbered attribute
        glBindBuffer(GL_ARRAY_BUFFER, bufferID);
        glVertexAttribPointer(attribIndex,
                elementsPerVertex,
                glType,
                isNormalized,
                byteStride,
                BUFFER_OFFSET(byteOffset));
        glBindBuffer(GL_ARRAY_BUFFER, 0);
        
        error = glGetError();
        if(error != GL_NO_ERROR) {
            mexPrintf("(dotsMglSelectVertexAttributes) Error selecting vertex %s data.  glGetError()=%d\n",
                    attribName, error);
            continue;
        }
        
        // success for this attribute
        nSelected++;
    }
    
    // need to re-link the program when binding attribute names
    if (nNames > 0){
        glLinkProgram(programID);
        error = glGetError();
        if (error != GL_NO_ERROR) {
            mexPrintf("(dotsMglSelectVertexAttributes) Could not link program.  glGetError()=%d\n",
                    error);
            plhs[0] = mxCreateDoubleScalar(-10);
            return;
        }
    }
    
    // success?
    plhs[0] = mxCreateDoubleScalar(nSelected);
}
void LTFAT_NAME(ltfatMexFnc)( int nlhs, mxArray *plhs[],int nrhs, const mxArray *prhs[] )
{
  #ifdef _DEBUG
  static int atExitFncRegistered = 0;
  if(!atExitFncRegistered)
  {
     LTFAT_NAME(ltfatMexAtExit)(LTFAT_NAME(tdMexAtExitFnc));
     atExitFncRegistered = 1;
  }
  #endif

  const mxArray* mxf = prhs[0];
  const mxArray* mxg = prhs[1];
  double* a = (double*) mxGetData(prhs[2]);
  double* offset = (double*) mxGetData(prhs[3]);
  char* ext = mxArrayToString(prhs[4]);


  // input data length
  mwSize L = mxGetM(mxf);
  // number of channels
  mwSize W = mxGetN(mxf);
  // filter number
  mwSize M = mxGetNumberOfElements(mxg);
  // filter lengths
  mwSize filtLen[M];
  //mwSize* filtLen = mxMalloc(M*sizeof(mwSize));
  for(unsigned int m=0;m<M;m++)
  {
     filtLen[m] = (mwSize) mxGetNumberOfElements(mxGetCell(mxg,m));
  }

  // output lengths
  mwSize outLen[M];
  //mwSize* outLen = mxMalloc(M*sizeof(mwSize));
  if(!strcmp(ext,"per"))
  {
     for(unsigned int m = 0; m < M; m++)
     {
        outLen[m] = (mwSize) ceil( L/a[m] );
     }
  }
  else if(!strcmp(ext,"valid"))
  {
     for(unsigned int m = 0; m < M; m++)
     {
        outLen[m] = (mwSize) ceil( (L-(filtLen[m]-1))/a[m] );
     }
  }
  else
  {
     for(unsigned int m = 0; m < M; m++)
     {
        outLen[m] = (mwSize) ceil( (L + filtLen[m] - 1 + offset[m] )/a[m] );
     }
  }

     // POINTER TO THE INPUT
     LTFAT_TYPE* fPtr = (LTFAT_TYPE*) mxGetData(prhs[0]);

     // POINTER TO THE FILTERS
     LTFAT_TYPE* gPtrs[M];
     // LTFAT_TYPE** gPtrs = (LTFAT_TYPE**) mxMalloc(M*sizeof(LTFAT_TYPE*));
     for(mwIndex m=0;m<M;m++)
     {
        gPtrs[m] = (LTFAT_TYPE*) mxGetPr(mxGetCell(mxg, m));
     }

     // POINTER TO OUTPUTS
     LTFAT_TYPE* cPtrs[M]; // C99 feature
     //LTFAT_TYPE** cPtrs = (LTFAT_TYPE**) mxMalloc(M*sizeof(LTFAT_TYPE*));
     plhs[0] = mxCreateCellMatrix(M, 1);
     for(mwIndex m=0;m<M;++m)
     {
        mxSetCell(plhs[0], m, ltfatCreateMatrix(outLen[m], W,LTFAT_MX_CLASSID,LTFAT_MX_COMPLEXITY));
        cPtrs[m] = (LTFAT_TYPE*) mxGetData(mxGetCell(plhs[0],m));
        memset(cPtrs[m],0,outLen[m]*W*sizeof(LTFAT_TYPE));
     }

     // over all channels
   //  #pragma omp parallel for private(m)

        for(mwIndex m =0; m<M; m++)
        {
          for(mwIndex w =0; w<W; w++)
          {
           // Obtain pointer to w-th column in input
           LTFAT_TYPE *fPtrCol = fPtr + w*L;
           // Obtaing pointer to w-th column in m-th element of output cell-array
           LTFAT_TYPE *cPtrCol = cPtrs[m] + w*outLen[m];
           //conv_td_sub(fPtrCol,L,&cPtrCol,outLen[m],(const double**)&gPtrs[m],filtLen[m],1,a[m],skip[m],ltfatExtStringToEnum(ext),0);
           LTFAT_NAME(convsub_td)(fPtrCol,L,cPtrCol,outLen[m],gPtrs[m],filtLen[m],a[m],-offset[m],ltfatExtStringToEnum(ext));
          }
        }
}
Beispiel #13
0
void recurse_object(const mxArray* in, json& obj)
{
    // Go over all types
    if (mxIsCell(in)) {
        int N = mxGetNumberOfElements(in);
        for (int a = 0; a < N; ++a) {           
            obj.emplace_back();
            recurse_object(mxGetCell(in, a), obj.back());
        }
    } else if (mxIsStruct(in)) {
        int M = mxGetNumberOfFields(in);
        std::vector<const char*> fnames(M);
        for (int b = 0; b < M; ++b)
            fnames[b] = mxGetFieldNameByNumber(in, b);
        int N = mxGetNumberOfElements(in);
        for (int a = 0; a < N; ++a) {
            json obj_;
            for (int b = 0; b < M; ++b)
                recurse_object(mxGetFieldByNumber(in, a, b), obj_[fnames[b]]);
            if (N == 1)
                obj = std::move(obj_);
            else
                obj.push_back(std::move(obj_));
        }
    } else if (mxIsChar(in)) {
        obj = json::parse(mxArrayToString(in));
    } else if (mxIsLogical(in)) {
        int N = mxGetNumberOfElements(in);
        const mxLogical* data = (const mxLogical*)mxGetData(in);
        if (N == 1) {
            obj = data[0] != 0;
        } else {
            for (int a = 0; a < N; ++a)
                obj.push_back(data[a] != 0);
        }
    } else if (mxIsNumeric(in)) {
        int N = mxGetNumberOfElements(in);
        const void* data = (const void*)mxGetData(in);
        switch (mxGetClassID(in)) {
            case mxDOUBLE_CLASS:
                if (N == 1) { obj = ((const double*)data)[0]; } else {
                for (int a = 0; a < N; ++a) obj.push_back(((const double*)data)[a]); }
                break;
            case mxSINGLE_CLASS:
                if (N == 1) { obj = ((const float*)data)[0]; } else {
                for (int a = 0; a < N; ++a) obj.push_back(((const float*)data)[a]); }
                break;
            case mxUINT8_CLASS:
                if (N == 1) { obj = ((const uint8_t*)data)[0]; } else {
                for (int a = 0; a < N; ++a) obj.push_back(((const uint8_t*)data)[a]); }
                break;
            case mxINT8_CLASS:
                if (N == 1) { obj = ((const int8_t*)data)[0]; } else {
                for (int a = 0; a < N; ++a) obj.push_back(((const int8_t*)data)[a]); }
                break;
            case mxUINT16_CLASS:
                if (N == 1) { obj = ((const uint16_t*)data)[0]; } else {
                for (int a = 0; a < N; ++a) obj.push_back(((const uint16_t*)data)[a]); }
                break;
            case mxINT16_CLASS:
                if (N == 1) { obj = ((const int16_t*)data)[0]; } else {
                for (int a = 0; a < N; ++a) obj.push_back(((const int16_t*)data)[a]); }
                break;
            case mxUINT32_CLASS:
                if (N == 1) { obj = ((const uint32_t*)data)[0]; } else {
                for (int a = 0; a < N; ++a) obj.push_back(((const uint32_t*)data)[a]); }
                break;
            case mxINT32_CLASS:
                if (N == 1) { obj = ((const int32_t*)data)[0]; } else {
                for (int a = 0; a < N; ++a) obj.push_back(((const int32_t*)data)[a]); }
                break;
            case mxUINT64_CLASS:
                if (N == 1) { obj = ((const uint64_t*)data)[0]; } else {
                for (int a = 0; a < N; ++a) obj.push_back(((const uint64_t*)data)[a]); }
                break;
            case mxINT64_CLASS:
                if (N == 1) { obj = ((const int64_t*)data)[0]; } else {
                for (int a = 0; a < N; ++a) obj.push_back(((const int64_t*)data)[a]); }
                break;
            default:
                mexErrMsgTxt("Unsupported type.");
                break;
        }
    } else {
		mexErrMsgTxt("Unrecognized type.");
    }
}
/*
%COMP_IFILTERBANK_TD   Synthesis filterbank
%   Usage:  f=comp_ifilterbank_fft(c,g,a,Ls,offset,ext);
%
%   Input parameters:
%         c    : Cell array of length M, each element is N(m)*W matrix.
%         g    : Filterbank filters - length M cell-array, each element is vector of length filtLen(m)
%         a    : Upsampling factors - array of length M.
%         offset : Delay of the filters - scalar or array of length M.
%         Ls   : Output length.
%         ext  : Border exension technique.
%
%   Output parameters:
%         f  : Output Ls*W array.
%
*/
void LTFAT_NAME(ltfatMexFnc)( int nlhs, mxArray *plhs[],int nrhs, const mxArray *prhs[] )
{
  // printf("Filename: %s, Function name %s, %d \n.",__FILE__,__func__,mxIsDouble(prhs[0]));
  const mxArray* mxc = prhs[0];
  const mxArray* mxg = prhs[1];
  double* a = mxGetPr(prhs[2]);
  double* Lsdouble = mxGetPr(prhs[3]);
  unsigned int Ls = (unsigned int) *Lsdouble;
  double* offset = mxGetPr(prhs[4]);
  char* ext = mxArrayToString(prhs[5]);

  // number of channels
  unsigned int W = mxGetN(mxGetCell(mxc,0));

  // filter number
  unsigned int M = mxGetNumberOfElements(mxg);

  // input data length
  unsigned int* Lc = mxMalloc(M*sizeof(unsigned int));
  for(unsigned int m=0;m<M;m++)
  {
     Lc[m] = (unsigned int) mxGetM(mxGetCell(mxc,m));
  }

  // filter lengths
  unsigned int* filtLen = mxMalloc(M*sizeof(unsigned int));
  for(unsigned int m=0;m<M;m++)
  {
     filtLen[m] = (unsigned int) mxGetNumberOfElements(mxGetCell(mxg,m));
  }

     // POINTER TO THE INPUT
     LTFAT_TYPE** cPtrs = (LTFAT_TYPE**) mxMalloc(M*sizeof(LTFAT_TYPE*));
     for(unsigned int m=0;m<M;++m)
     {
        cPtrs[m] = (LTFAT_TYPE*) mxGetData(mxGetCell(mxc,m));
     }

     // allocate output
     plhs[0] = ltfatCreateMatrix(Ls, W,LTFAT_MX_CLASSID,LTFAT_MX_COMPLEXITY);


      // POINTER TO OUTPUT
     LTFAT_TYPE* fPtr = (LTFAT_TYPE*) mxGetData(plhs[0]);
     // Set to zeros
     memset(fPtr,0,Ls*W*sizeof(LTFAT_TYPE));

     // POINTER TO THE FILTERS
     LTFAT_TYPE** gPtrs = (LTFAT_TYPE**) mxMalloc(M*sizeof(LTFAT_TYPE*));
     for(unsigned int m=0;m<M;m++)
     {
        gPtrs[m] = (LTFAT_TYPE*) mxGetData(mxGetCell(mxg, m));
     }

     // over all channels
   //  #pragma omp parallel for private(m)

        for(unsigned int m =0; m<M; m++)
        {
          for(unsigned int w =0; w<W; w++)
          {
           // Obtain pointer to w-th column in input
           LTFAT_TYPE *fPtrCol = fPtr + w*Ls;
           // Obtaing pointer to w-th column in m-th element of output cell-array
           LTFAT_TYPE *cPtrCol = cPtrs[m] + w*Lc[m];
           //(upconv_td)(const LTFAT_TYPE *in, int inLen, LTFAT_TYPE *out, const int outLen, const LTFAT_TYPE *filts, int fLen, int up, int skip, enum ltfatWavExtType ext)
           LTFAT_NAME(upconv_td)(cPtrCol,Lc[m],fPtrCol,Ls,gPtrs[m],filtLen[m],a[m],-offset[m],ltfatExtStringToEnum(ext));
          }
       }

}
MVT_3D_Object::MVT_3D_Object(ENUM_OBJECT_CATEGORY object_category, const char* filepath_3dobject_model)
{
	m_object_category = object_category;

	MATFile* mat = matOpen(filepath_3dobject_model,"r");
	if( mat != NULL )
	{
		mxArray* pmxCad = matGetVariable(mat, "cad");
		pmxCad = mxGetCell(pmxCad,0);

		/*
		 * Names of parts
		 */
		mxArray* pmxNames    = mxGetField(pmxCad, 0, "pnames");
		m_num_of_partsNroots = mxGetNumberOfElements(pmxNames);
		for( unsigned int i=0; i<m_num_of_partsNroots; i++)
		{
			mxArray* pmxName = mxGetCell(pmxNames, i);
			m_names_partsNroots.push_back(MxArray(pmxName).toString());
		}

		/*
		 * Parts2d_Front
		 */
		mxArray* pmxPars2d_front = mxGetField(pmxCad, 0, "parts2d_front");
		for( unsigned int i=0; i<m_num_of_partsNroots; i++)
		{
			MVT_2D_Part_Front front;
			front.width    = MxArray(mxGetField(pmxPars2d_front, i, "width"   )).toDouble();
			front.height   = MxArray(mxGetField(pmxPars2d_front, i, "height"  )).toDouble();
			front.distance = MxArray(mxGetField(pmxPars2d_front, i, "distance")).toDouble();

			cv::Mat mat_tmp = MxArray(mxGetField(pmxPars2d_front, i, "vertices")).toMat();
			unsigned int n_row = mat_tmp.rows;
			for( unsigned int r=0; r<n_row ; r++)
			{
				front.vertices.push_back(cv::Point2d(mat_tmp.at<double>(r,0), mat_tmp.at<double>(r,1)));
			}

			front.center   = MxArray(mxGetField(pmxPars2d_front, i, "center")).toPoint_<double>();
			front.viewport = MxArray(mxGetField(pmxPars2d_front, i, "viewport")).toDouble();
			front.name     = MxArray(mxGetField(pmxPars2d_front, i, "pname")).toString();

			m_2dparts_front.push_back(front);
		}

		/*
		 * Part
		 */
		mxArray* pmxParts = mxGetField(pmxCad, 0, "parts");
		m_num_of_parts = mxGetNumberOfElements(pmxParts);

		for( unsigned int i=0 ; i<m_num_of_parts; i++ )
		{
			MVT_3D_Part part;

			/* Vertices */
			mxArray* mxVertices = mxGetField(pmxParts, i, "vertices");
			cv::Mat matVertices = MxArray(mxVertices).toMat();

			unsigned int n_rows = matVertices.rows;
			for( unsigned int r=0; r<n_rows; r++)
			{
				cv::Mat matTmp = matVertices.row(r);

				part.vertices.push_back
				(
					cv::Point3d( matTmp.at<double>(0),
								 matTmp.at<double>(1),
								 matTmp.at<double>(2)  )
				);
			}

			/* plane */
			MxArray MxPlane(mxGetField(pmxParts, i, "plane"));
			for( int j=0 ; j<4; j++ )
			{
				part.plane[j] = MxPlane.at<double>(j);
			}

			/* center */
			MxArray MxCenter(mxGetField(pmxParts, i, "center"));
			part.center.x = MxCenter.at<double>(0);
			part.center.y = MxCenter.at<double>(1);
			part.center.z = MxCenter.at<double>(2);

			/* xaxis */
			MxArray MxXAxis(mxGetField(pmxParts, i, "xaxis"));
			part.xaxis.x = MxXAxis.at<double>(0);
			part.xaxis.y = MxXAxis.at<double>(1);
			part.xaxis.z = MxXAxis.at<double>(2);

			/* yaxis */
			MxArray MxYAxis(mxGetField(pmxParts, i, "yaxis"));
			part.yaxis.x = MxYAxis.at<double>(0);
			part.yaxis.y = MxYAxis.at<double>(1);
			part.yaxis.z = MxYAxis.at<double>(2);

			m_3dparts.push_back(part);

			/*
			 * Occlusion Information
			 */
			mxArray* pmxAzimuth   = mxGetField(pmxCad, 0, "azimuth" );
			m_disc_azimuth        = MxArray(pmxAzimuth).toVector<MVT_AZIMUTH>();

			mxArray* pmxElevation = mxGetField(pmxCad, 0, "elevation" );
			m_disc_elevation      = MxArray(pmxElevation).toVector<MVT_ELEVATION>();

			mxArray* pmxDistance  = mxGetField(pmxCad, 0, "distance" );
			m_disc_distance       = MxArray(pmxDistance).toVector<MVT_DISTANCE>();

			mxArray* pmxParts2d   = mxGetField(pmxCad, 0, "parts2d");

			m_num_of_disc_azimuth   = m_disc_azimuth.size();
			m_num_of_disc_elevation = m_disc_elevation.size();
			m_num_of_disc_distance  = m_disc_distance.size();

			m_is_occluded = new bool***[m_num_of_disc_azimuth];
			for( unsigned int a=0; a<m_num_of_disc_azimuth; a++ )
			{
				m_is_occluded[a] = new bool**[m_num_of_disc_elevation];
				for( unsigned int e=0; e<m_num_of_disc_elevation; e++ )
				{
					m_is_occluded[a][e] = new bool*[m_num_of_disc_distance];
					for( unsigned int d=0; d<m_num_of_disc_distance; d++ )
					{
						m_is_occluded[a][e][d] = new bool[m_num_of_partsNroots];
						unsigned int idx = m_num_of_disc_distance*m_num_of_disc_elevation*a +
								             m_num_of_disc_distance*e +
								             d;
						for( unsigned int p=0; p<m_num_of_partsNroots; p++)
						{
							mxArray* pmxPart = mxGetField(pmxParts2d, idx, m_names_partsNroots[p].c_str());
							m_is_occluded[a][e][d][p] = mxIsEmpty(pmxPart);
						}
					}
				}
			}
		}

		mxDestroyArray(pmxCad);
		matClose(mat);
	}
}
Beispiel #16
0
void mexFunction( int nlhs, mxArray *plhs[],int nrhs, const mxArray *prhs[] )
{
    if(nrhs < 4 || nrhs > 5)
     mexErrMsgTxt("Improper number of input arguments.\n\n"
                  "ARGMAX_MEX estimates the position of landmarks.\n\n"
                  "Synopsis: \n"
                  "  [ \\hat{s} ]= argmax_mex(options, W, mapTable, lbp [, L]) \n"
                  "\n"
                  "  Input: \n"
                  "    options [1 x 1 structure] detector options\n"
                  "    W [n x 1 (double)] joint parameter vector\n"
                  "    mapTable [M x 4 (double)] mapping table for joint parameter vector W\n"
                  "    lbp [1 x M (cell)] LBP sparse features\n"
                  "    L [M x 1 (cell)] precomputed losses, optional parameter (for learning stage)\n"
                  "  Output: \n"
                  "    \\hat{s} [M x 2 (double)] estimated landmark positions\n");
    
    //--------------------------------------------------------------------------
    // Load input
    double * W;
    uint32_t W_ROWS, W_COLS;
    
    FLANDMARK_Options options;
    uint8_t M;
    const mwSize *dims;
    double * tmp_ptr;
    mxArray *tmp_field_ptr, *cell_ptr;
    
    mxArray * psigs0 = mxGetField(prhs[0], 0, "PsiGS0");
    dims = mxGetDimensions(psigs0);
    options.PSIG_ROWS[0] = dims[0];
    options.PSIG_COLS[0] = dims[1];
    mxArray * psigs1 = mxGetField(prhs[0], 0, "PsiGS1");
    dims = mxGetDimensions(psigs1);
    options.PSIG_ROWS[1] = dims[0];
    options.PSIG_COLS[1] = dims[1];
    mxArray * psigs2 = mxGetField(prhs[0], 0, "PsiGS2");
    dims = mxGetDimensions(psigs2);
    options.PSIG_ROWS[2] = dims[0];
    options.PSIG_COLS[2] = dims[1];

    int tsize = -1, rows = -1, cols = -1;
    double * result;    
    bool lossy = (nrhs > 4) ? true : false;
    
    // options ----------------------------------------------------------------
    //options.M = 7;
    tmp_field_ptr = mxGetField(prhs[0], 0, "M");
    tmp_ptr = (double*)mxGetPr(tmp_field_ptr);
    options.M = (int)tmp_ptr[0];
    M = options.M;
    
    //int mapTable[7*4];
    int * mapTable = (int*)calloc(M*4, sizeof(int));
    options.S = (int*)calloc(4*M, sizeof(int));
    
    // options.S ---------------------------------------------------
    tmp_field_ptr = mxGetField(prhs[0], 0, "S");
    dims = mxGetDimensions(tmp_field_ptr);
    tmp_ptr = (double*)mxGetPr(tmp_field_ptr);
    for (int i = 0; i < 4*options.M; ++i)
    {
        options.S[i] = (int)tmp_ptr[i];
    }
    
    // W ----------------------------------------------------------------------
    dims = mxGetDimensions(prhs[1]);
    W_ROWS = dims[0]; W_COLS = dims[1];
    bool WisSparse = mxIsSparse(prhs[1]);
    if (WisSparse)
    {
        W = (double*)calloc(W_ROWS*W_COLS, sizeof(double));
        double * pr = (double*)mxGetPr(prhs[1]);
        mwIndex * ir = mxGetIr(prhs[1]);
        mwSize nzmax = mxGetNzmax(prhs[1]);
        for (int ii = 0; ii < nzmax; ++ii)
        {
            W[ir[ii]] = pr[ii];
        }
    } else {
        W = (double*)mxGetPr(prhs[1]);
    }
    // ------------------------------------------------------------------------
    
    // mapTable
    tmp_ptr = (double*)mxGetPr(prhs[2]);
    dims = mxGetDimensions(prhs[2]);
    if (dims[0]*dims[1] != M*4)
    {
        mexErrMsgTxt("mapTable must be a matrix [M x 4 (double)]");
    }
    for (int i = 0; i < M*4; ++i)
    {
        mapTable[i] = (int)tmp_ptr[i];
    }
    
    // prepare output matrix
    plhs[0] = mxCreateNumericMatrix(2, M, mxDOUBLE_CLASS, mxREAL);
    result = (double*)mxGetPr(plhs[0]);
    
    //--------------------------------------------------------------------------
    // get Q, G
    double ** q = (double**)calloc(M, sizeof(double*));
    double ** g = (double**)calloc((M-1), sizeof(double*));

    int idx_qtemp = 0;

    double * L;
    
    for (int idx = 0; idx < M; ++idx)
    {
        // Q
        tsize = mapTable[INDEX(idx, 1, M)] - mapTable[INDEX(idx, 0, M)] + 1;

        double * q_temp = (double*)calloc(tsize, sizeof(double));
        memcpy(q_temp, W+mapTable[INDEX(idx, 0, M)]-1, tsize*sizeof(double));

        // sparse dot product <W_q, PSI_q>
        cell_ptr = mxGetCell(prhs[3], idx);
        dims = mxGetDimensions(cell_ptr);
        cols = dims[1];
        rows = dims[0];
        uint32_t *psi_temp = (uint32_t*)mxGetPr(cell_ptr);
        if (lossy)
        {
            L = (double*)mxGetPr(mxGetCell(prhs[4], idx));
        }
        q[idx] = (double*)malloc(cols*sizeof(double));
        for (int i = 0; i < cols; ++i)
        {
            double dotprod = 0.0f;
            for (int j = 0; j < rows; ++j)
            {
                idx_qtemp = psi_temp[(rows*i) + j];
                dotprod += q_temp[ idx_qtemp ];
            }
            q[idx][i] = dotprod;
            if (lossy)
            {
                q[idx][i] += L[i];
            }
        }
        free(q_temp);

        // G
        if (idx > 0)
        {
            tsize = mapTable[INDEX(idx, 3, M)] - mapTable[INDEX(idx, 2, M)] + 1;
            g[idx - 1] = (double*)malloc(tsize*sizeof(double));
            memcpy(g[idx - 1], W+mapTable[INDEX(idx, 2, M)]-1, tsize*sizeof(double));
        }
    }
        
    // compute argmax
    int * indices = (int*)malloc(M*sizeof(int));
    tsize = mapTable[INDEX(1, 3, M)] - mapTable[INDEX(1, 2, M)] + 1;

    // left branch - store maximum and index of s5 for all positions of s1
    dims = mxGetDimensions(mxGetCell(prhs[3], 1)); 
    int q1_length = dims[1];
    
    double * s1 = (double *)calloc(2*q1_length, sizeof(double));
    double * s1_maxs = (double *)calloc(q1_length, sizeof(double));
    for (int i = 0; i < q1_length; ++i)
    {
        // dot product <g_5, PsiGS1>
        dims = mxGetDimensions(mxGetCell(psigs1, INDEX(i, 0, options.PSIG_ROWS[1])));
        maximize_gdotprod(
            &s1[INDEX(0, i, 2)], &s1[INDEX(1, i, 2)],
            q[5], g[4], (double*)mxGetPr(mxGetCell(psigs1, INDEX(i, 0, options.PSIG_ROWS[1]))),
            dims[1], tsize);
        
        s1[INDEX(0, i, 2)] += q[1][i];
    }
    for (int i = 0; i < q1_length; ++i)
    {
        s1_maxs[i] = s1[INDEX(0, i, 2)];
    }
    
    // right branch (s2->s6) - store maximum and index of s6 for all positions of s2
    dims = mxGetDimensions(mxGetCell(prhs[3], 2));
    int q2_length = dims[1];
    
    double * s2 = (double *)calloc(2*q2_length, sizeof(double));
    double * s2_maxs = (double *)calloc(q2_length, sizeof(double));
    for (int i = 0; i < q2_length; ++i)
    {
        // dot product <g_6, PsiGS2>     
        dims = mxGetDimensions(mxGetCell(psigs2, INDEX(i, 0, options.PSIG_ROWS[2])));
        maximize_gdotprod(
                &s2[INDEX(0, i, 2)], (double*)&s2[INDEX(1, i, 2)],
                q[6], g[5], (double*)mxGetPr(mxGetCell(psigs2, INDEX(i, 0, options.PSIG_ROWS[2]))),
                dims[1], tsize);
        s2[INDEX(0, i, 2)] += q[2][i];
    }
    for (int i = 0; i < q2_length; ++i)
    {
        s2_maxs[i] = s2[INDEX(0, i, 2)];
    }
   
    // the root s0 and its connections
    dims = mxGetDimensions(mxGetCell(prhs[3], 0)); 
    int q0_length = dims[1];
    double maxs0 = -FLT_MAX; 
    int maxs0_idx = -1;
    double maxq10 = -FLT_MAX, maxq20 = -FLT_MAX, maxq30 = -FLT_MAX, maxq40 = -FLT_MAX, 
            maxq70 = -FLT_MAX;
    double * s0 = (double *)calloc(M*q0_length, sizeof(double));
    
    for (int i = 0; i < q0_length; ++i)
    {
        // q10
        maxq10 = -FLT_MAX;
        dims = mxGetDimensions(mxGetCell(psigs0, INDEX(i, 0, options.PSIG_ROWS[0])));
        maximize_gdotprod(
                &maxq10, &s0[INDEX(1, i, M)],
                s1_maxs, g[0], (double*)mxGetPr(mxGetCell(psigs0, INDEX(i, 0, options.PSIG_ROWS[0]))),
                dims[1], tsize);
        s0[INDEX(5, i, M)] = s1[INDEX(1, (int)s0[INDEX(1, i, M)], 2)];
        
        // q20
        maxq20 = -FLT_MAX;
        dims = mxGetDimensions(mxGetCell(psigs0, INDEX(i, 1, options.PSIG_ROWS[0])));
        maximize_gdotprod(
                &maxq20, &s0[INDEX(2, i, M)],
                s2_maxs, g[1], (double*)mxGetPr(mxGetCell(psigs0, INDEX(i, 1, options.PSIG_ROWS[0]))),
                dims[1], tsize);
        s0[INDEX(6, i, M)] = s2[INDEX(1, (int)s0[INDEX(2, i, M)], 2)];
        
        // q30
        maxq30 = -FLT_MAX;
        dims = mxGetDimensions(mxGetCell(psigs0, INDEX(i, 2, options.PSIG_ROWS[0])));
        maximize_gdotprod(
                &maxq30, &s0[INDEX(3, i, M)],
                q[3], g[2], (double*)mxGetPr(mxGetCell(psigs0, INDEX(i, 2, options.PSIG_ROWS[0]))),
                dims[1], tsize);
        
        // q40
        maxq40 = -FLT_MAX;
        dims = mxGetDimensions(mxGetCell(psigs0, INDEX(i, 3, options.PSIG_ROWS[0])));
        maximize_gdotprod(
                &maxq40, &s0[INDEX(4, i, M)],
                q[4], g[3], (double*)mxGetPr(mxGetCell(psigs0, INDEX(i, 3, options.PSIG_ROWS[0]))),
                dims[1], tsize);
        
        // q70
        maxq70 = -FLT_MAX;
        dims = mxGetDimensions(mxGetCell(psigs0, INDEX(i, 4, options.PSIG_ROWS[0])));
        maximize_gdotprod(
                &maxq70, &s0[INDEX(7, i, M)],
                q[7], g[6], (double*)mxGetPr(mxGetCell(psigs0, INDEX(i, 4, options.PSIG_ROWS[0]))),
                dims[1], tsize);
        
        // sum q10+q20+q30+q40+q70
        if (maxs0 < maxq10+maxq20+maxq30+maxq40+maxq70+q[0][i])
        {
            maxs0_idx = i;
            s0[INDEX(0, i, M)] = i;
            maxs0 = maxq10+maxq20+maxq30+maxq40+maxq70+q[0][i];
        }
    }
    
    // get indices
    for (int i = 0; i < M; ++i)
    {
        indices[i] = (int)s0[INDEX(0, maxs0_idx, M)+i]+1;
    }

    // cleanup temp variables
    free(s0);
    free(s1); free(s1_maxs);
    free(s2); free(s2_maxs);

    // cleanup W if it was created
    if (WisSparse)
    {
        free(W);
    }
    
    // cleanup q
    for (int i = 0; i < M; ++i)
    {
        free(q[i]);
    }
    free(q);
    // cleanup g
    for (int i = 0; i < M - 1; ++i)
    {
        free(g[i]);
    }
    free(g);
    
    // convert 1D indices to 2D coordinates of estimated positions
    int * optionsS = &options.S[0];
    for (int i = 0; i < M; ++i)
    {
        int rows = optionsS[INDEX(3, i, 4)] - optionsS[INDEX(1, i, 4)] + 1;
        result[INDEX(0, i, 2)] = COL(indices[i], rows) + optionsS[INDEX(0, i, 4)];
        result[INDEX(1, i, 2)] = ROW(indices[i], rows) + optionsS[INDEX(1, i, 4)];
    }
    free(indices);
    free(options.S);
    free(mapTable);
    
    return;
}
Beispiel #17
0
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");
			}
		}
	}
//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);

}
Beispiel #19
0
void
mexFunction(int nlhs, mxArray * plhs[], int nrhs, const mxArray * prhs[]) {
   char *filename;
   FILE *dta_file;
   int ret = 0;

   filename = (char *)malloc(1 + mxGetN(prhs[0]));
   mxGetString(prhs[0], filename, 1 + mxGetN(prhs[0]));

   char *ws = (char *)malloc(1 + mxGetN(prhs[3]));
   mxGetString(prhs[3], ws, 1 + mxGetN(prhs[3]));

   unsigned short total_names_length = 0;
   for(unsigned short i = 0; i < 3; i++)
      total_names_length += mxGetN(mxGetCell(prhs[1], i));

   char *var_names_storage = (char *)malloc(3 + total_names_length);
   char *var_names[3];

   var_names[0] = var_names_storage;
   var_names[1] = var_names[0] + 1 + mxGetN(mxGetCell(prhs[1], 0));
   var_names[2] = var_names[1] + 1 + mxGetN(mxGetCell(prhs[1], 1));

   for(unsigned short i = 0; i < 3; i++) {
      mxArray *the_var_name = mxGetCell(prhs[1], i);
      mxGetString(the_var_name, var_names[i], 1 + mxGetN(the_var_name));
   }

   mxLogical *options = mxGetLogicals(prhs[2]);

   debug_msg(2, "opening: %s\n", filename);

   dta_file = fopen(filename, "rb");
   if(!dta_file)
      mexErrMsgTxt("Error opening file.");
   
   // allocate on the heap so that memory debugging libraries that don't perform bounds checking
   // for stack based allocations will work.
   setup_control *setup_c = (setup_control *)malloc(sizeof(setup_control));
   mx_m1_control *m1_c = (mx_m1_control *)malloc(sizeof(mx_m1_control));
   mx_m2_control *m2_c = (mx_m2_control *)malloc(sizeof(mx_m2_control));
   mx_m173_control *m173_c = (mx_m173_control *)malloc(sizeof(mx_m173_control));
   mx_m211_control *m211_c = (mx_m211_control *)malloc(sizeof(mx_m211_control));
   m110_data *p_info = (m110_data *)malloc(sizeof(m110_data));
   
   memset(setup_c, 0, sizeof(setup_control));
   memset(m1_c, 0, sizeof(mx_m1_control));
   memset(m2_c, 0, sizeof(mx_m2_control));
   memset(m173_c, 0, sizeof(mx_m173_control));
   memset(m211_c, 0, sizeof(mx_m211_control));
   memset(p_info, 0, sizeof(m110_data));
   
   int n_pp_segs = 0;

   setup_c->m1_c = m1_c;
   setup_c->m2_c = m2_c;
   setup_c->m173_c = m173_c;
   setup_c->m211_c = m211_c;
   setup_c->input_file_handle = dta_file;
   setup_c->options = options;
   m1_c->partial_power_segs_p = m2_c->partial_power_segs_p = &n_pp_segs;

   m173_c->n_hitbased = m1_c->n_hitbased;

   m1_c->has_waveforms = &m173_c->has_waveforms;
   m1_c->process_waveforms = (bool)options[2];
   
   m1_c->last_waveform_tot = m173_c->last_tot;
   m173_c->last_hit_tot = m1_c->last_tot;
   for(int i=0; i < (__AE_NUM_CHANNELS + 1); i++) {
      m173_c->last_tot[i] = -1.0;
      m1_c->last_tot[i] = -1.0;
   }
      

   m1_c->parametric_info = p_info;

   memset(mx_ctx, NULL, sizeof(mx_ctx));
   mx_ctx[1] = m1_c;
   mx_ctx[2] = m2_c;
   mx_ctx[5] = m1_c;
   mx_ctx[6] = m2_c;
   mx_ctx[8] = dta_file;
   mx_ctx[23] = m173_c;
   mx_ctx[24] = m173_c;
   mx_ctx[26] = m173_c;
   mx_ctx[42] = dta_file;
   mx_ctx[109] = &n_pp_segs;
   mx_ctx[106] = setup_c;
   mx_ctx[110] = m1_c;
   mx_ctx[128] = setup_c;
   mx_ctx[173] = m173_c;
   mx_ctx[211] = m211_c;   

   mx_setup_handlers_init(options[0], options[1], options[2], options[3]);
   parse_dta_file(mx_handlers, mx_ctx, dta_file);
   ret = setup(setup_c);
   if(ret != 0) {
      debug_msg(CRITICAL_MSG, "Setup was not successful\n");
      goto done;
   }
   
   rewind(dta_file);

   debug_msg(2, "setup complete...\n");

   mx_handlers_init(options[0], options[1], options[2], options[3]);
   parse_dta_file(mx_handlers, mx_ctx, dta_file);
   
   debug_msg(2, "parsing complete...\n");  

   if(options[0])
      mexPutVariable(ws, var_names[0], m1_c->matlab_array_handle);
   if(options[1])
      mexPutVariable(ws, var_names[1], m2_c->matlab_array_handle);
   if(options[3])
      mexPutVariable(ws, var_names[2], m211_c->matlab_array_handle);
      
   debug_msg(2, "done...\n");      
      
   done:
      if(m1_c->characteristics)
         free(m1_c->characteristics);
      if(m2_c->characteristics)
         free(m2_c->characteristics);
      if(m2_c->parametrics)
         free(m2_c->parametrics);
      if(p_info->pids)
         free(p_info->pids);   
   
      free(setup_c);
      free(m1_c);
      free(m2_c);
      free(m173_c);
      free(m211_c);
      free(p_info);
}
Beispiel #20
0
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
PVs     pvs = { {0} };
int     i,j,ij,n;
LcaError theErr;
MultiArgRec	args[1];
enum_states *strbuf MAY_ALIAS = 0;
mxArray *tmp;

	lcaErrorInit(&theErr);

	LHSCHECK(nlhs, plhs);

	if ( nlhs > 1 ) {
		lcaSetError(&theErr, EZCA_INVALIDARG, "Too many output args");
		goto cleanup;
	}

	if ( nrhs < 1 || nrhs > 1 ) {
		lcaSetError(&theErr, EZCA_INVALIDARG, "Expected 1 rhs argument");
		goto cleanup;
	}

	if ( buildPVs(prhs[0], &pvs, &theErr) )
		goto cleanup;

	MSetArg(args[0], sizeof(*strbuf), 0, &strbuf);

	if ( !multi_ezca_get_misc(pvs.names, pvs.m, (MultiEzcaFunc)ezcaGetEnumStrings, NumberOf(args), args, &theErr) )
		goto cleanup;

	n = EZCA_ENUM_STATES;

	/* convert string array to a matlab cell array of matlab strings */
	if ( !(plhs[0] = mxCreateCellMatrix(pvs.m, n)) ) {
		lcaSetError(&theErr, EZCA_FAILEDMALLOC, "Not enough memory");
		goto cleanup;
	}
	ij = 0;
	for ( j = 0; j < n; j++ ) {
		for ( i = 0; i < pvs.m; i++ ) {
			if ( !(tmp = mxCreateString(strbuf[i][j])) ) {
				for ( j=0; j<ij; j++ ) {
					mxDestroyArray(mxGetCell(plhs[0],ij));
				}
				mxDestroyArray(plhs[0]);
				plhs[0] = 0;
				lcaSetError(&theErr, EZCA_FAILEDMALLOC, "Not enough memory");
				goto cleanup;
			}
			mxSetCell(plhs[0], ij, (mxArray*)tmp);
			ij++;
		}
	}

	nlhs = 0;

cleanup:
	if ( strbuf )
		lcaFree( strbuf );
	releasePVs(&pvs);
	/* do this LAST (in case mexErrMsgTxt is called) */
	ERR_CHECK(nlhs, plhs, &theErr);
}
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 () ;
}
Beispiel #22
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();
}
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;

}   
Beispiel #24
0
void mexFunction(int nlhs, mxArray *plhs[], 
    int nrhs, const mxArray *prhs[])
{
	int dim, m, n, l, ntot, dims[3];
 	float *data1, *data2, *data20, *data21, *data22, *data23,*wx, *wy, *wz;
	double spline, nx, ny, nz, offx, offy, offz, mx, my, mz;
	size_t sizebuf;

	if (nrhs == 6)
	{
		spline = mxGetScalar(prhs[5]);
	}
	else if (nrhs == 5)
	{
		spline = 3;
	}
	else
	{
		mexPrintf("[Gxx Gyx Gzx Gxy Gyy Gzy Gxz Gyz Gzz] = "
		    "BsplCos2ValsMaskZero(COEFFx, COEFFy, COEFFz, "
		    "[nx ny nz], [offx offy offz], [mx my mz], MASK, deg);\n");
		mexPrintf("[in]\n");
		mexPrintf("\tCOEFFx COEFFy COEFFz: bspline coefficients - "
			"single type\n");
		mexPrintf("\t[nx ny nz]          : output dimension\n");
		mexPrintf("\t[offx offy offz]    : offset of the origin\n");
		mexPrintf("\t[mx my mz]          : magnification factor for "
			"each direction\n");
		mexPrintf("\tMASK                : MASK, non zeros");
		mexPrintf("\tdeg           	: (opt) spline basis degree "
			"{default: 3}\n");
		mexPrintf("[out]\n");
		mexPrintf("\tGx Gy Gz, x y z		: gradient values\n");
		return;
	}

    	if (mxIsSingle(prhs[0]) != 1)
        {
                mexErrMsgTxt("First argument must be of single type\n");
                return;
        }

    	/* Retrieve the input data */
    	data1 = mxGetData(prhs[0]);

	if (mxGetNumberOfDimensions(prhs[0]) == 2)
	{
		m = mxGetDimensions(prhs[0])[0];
		n = mxGetDimensions(prhs[0])[1];
		l = 1;
	}
	else if (mxGetNumberOfDimensions(prhs[0]) == 3)
	{
		m = mxGetDimensions(prhs[0])[0];
		n = mxGetDimensions(prhs[0])[1];
		l = mxGetDimensions(prhs[0])[2];
	}
	else 
	{
                mexErrMsgTxt("First argument must be 2D or 3D\n");
		return;
	}

	ntot = mxGetNumberOfElements(prhs[1]);
	dim = ntot;
	sizebuf = mxGetElementSize(prhs[1]);
	if (ntot == 2)
	{
		nx = *((double*)mxGetData(prhs[1]));
		ny = *((double*)(mxGetData(prhs[1]) + sizebuf));
		dims[0] = (int)nx;
		dims[1] = (int)ny;
	}
	else if (ntot == 3)
	{
		nx = *((double*)mxGetData(prhs[1]));
		ny = *((double*)(mxGetData(prhs[1]) + sizebuf));
		nz = *((double*)(mxGetData(prhs[1]) + 2*sizebuf));
		dims[0] = (int)nx;
		dims[1] = (int)ny;
		dims[2] = (int)nz;
	}
	else
	{
                mexErrMsgTxt("Second argument should be either [nx ny nz] or "
			"[nx ny]\n");
		return;
	}

	ntot = mxGetNumberOfElements(prhs[2]);
	sizebuf = mxGetElementSize(prhs[2]);
	if (ntot == 2)
	{
		offx = *((double*)mxGetData(prhs[2]));
		offy = *((double*)(mxGetData(prhs[2]) + sizebuf));
	}
	else if (ntot == 3)
	{
		offx = *((double*)mxGetData(prhs[2]));
		offy = *((double*)(mxGetData(prhs[2]) + sizebuf));
		offz = *((double*)(mxGetData(prhs[2]) + 2*sizebuf));
	}
	else
	{
		mexErrMsgTxt("Third argument should be either [offx offy offz]"
			" or [offx offy]\n");
		return;
	}

	ntot = mxGetNumberOfElements(prhs[3]);
	sizebuf = mxGetElementSize(prhs[3]);
	if (ntot == 2)
	{
		mx = *((double*)mxGetData(prhs[3]));
		my = *((double*)(mxGetData(prhs[3]) + sizebuf));
	}
	else if (ntot == 3)
	{
		mx = *((double*)mxGetData(prhs[3]));
		my = *((double*)(mxGetData(prhs[3]) + sizebuf));
		mz = *((double*)(mxGetData(prhs[3]) + 2*sizebuf));
	}
	else
	{
       		mexErrMsgTxt("Fourth argument should be either [mx my mz] or"
			" [mx my]\n");
       		return;
	}

        ntot = mxGetNumberOfElements(prhs[4]);
	if (ntot == 0)
	{
	}
        else if (ntot == 2)
        {
                wx = (float*)mxGetData(mxGetCell(prhs[4], 0));
                wy = (float*)mxGetData(mxGetCell(prhs[4], 1));
        }
        else if (ntot == 3)
        {
                wx = (float*)mxGetData(mxGetCell(prhs[4], 0));
                wy = (float*)mxGetData(mxGetCell(prhs[4], 1));
                wz = (float*)mxGetData(mxGetCell(prhs[4], 2));
        }
        else
        {
           	mexErrMsgTxt("Fifth argument should be {}, {wx wy wz} or "
			"{wx wy}\n");
           	return;
        }


    	/* Create an mxArray for the output data */
	if (dim == 3)
	{
		if (nlhs == 4)
		{
			plhs[0] = mxCreateNumericArray(
					mxGetNumberOfElements(prhs[1]), dims, 
					mxSINGLE_CLASS, mxREAL);
			plhs[1] = mxCreateNumericArray(
					mxGetNumberOfElements(prhs[1]), dims, 
					mxSINGLE_CLASS, mxREAL);
			plhs[2] = mxCreateNumericArray(
					mxGetNumberOfElements(prhs[1]), dims, 
					mxSINGLE_CLASS, mxREAL);
			plhs[3] = mxCreateNumericArray(
					mxGetNumberOfElements(prhs[1]), dims, 
					mxSINGLE_CLASS, mxREAL);

			data20 = mxGetData(plhs[0]);
			data21 = mxGetData(plhs[1]);
			data22 = mxGetData(plhs[2]);
			data23 = mxGetData(plhs[3]);
			if (ntot == 0) /* no warp */
			{
				BatchInterpolatedAll3DZero (
					data20, data21, data22, data23, data1,
					m, n, l, nx, offx, mx, ny, offy, my, 
					nz, offz, mz, (long)spline); 
			}
			else
			{
				BatchInterpolatedAll3DZeroWarp (
					data20, data21, data22, data23, data1,
					m, n, l, nx, offx, mx, wx, ny, offy, my,
 					wy, nz, offz, mz, wz, (long)spline); 
			}
		}
		else
		{
			plhs[0] = mxCreateNumericArray(
					mxGetNumberOfElements(prhs[1]), dims, 
					mxSINGLE_CLASS, mxREAL);
    	
			data2 = mxGetData(plhs[0]);
			if (ntot == 0) /* no warp */
			{
				BatchInterpolatedValue3DZero(data2, data1, 
					m, n, l, nx, offx, mx, ny, offy, my, 
					nz, offz, mz, (long)spline); 
			}
			else
			{
				BatchInterpolatedValue3DZeroWarp(data2, data1, 
					m, n, l, nx, offx, mx, wx, ny, offy, my,
 					wy, nz, offz, mz, wz, (long)spline); 
			}
		}
	}
	else
	{
		if (nlhs == 3)
		{
			plhs[0] = mxCreateNumericArray(
					mxGetNumberOfElements(prhs[1]), dims, 
					mxSINGLE_CLASS, mxREAL);
			plhs[1] = mxCreateNumericArray(
					mxGetNumberOfElements(prhs[1]), dims, 
					mxSINGLE_CLASS, mxREAL);
			plhs[2] = mxCreateNumericArray(
					mxGetNumberOfElements(prhs[1]), dims, 
					mxSINGLE_CLASS, mxREAL);

			data20 = mxGetData(plhs[0]);
			data21 = mxGetData(plhs[1]);
			data22 = mxGetData(plhs[2]);
			if (ntot == 0) /* no warp */
			{
				BatchInterpolatedValue2DZero(data20,data1, m, n,
					 nx, offx, mx, ny, offy, my, 
					(long)spline); 
				BatchInterpolatedGradX2DZero(data21,data1, m, n,
					 nx, offx, mx, ny, offy, my, 
					(long)spline); 
				BatchInterpolatedGradY2DZero(data22,data1, m, n,
					 nx, offx, mx, ny, offy, my, 
					(long)spline); 
			}
			else
			{
				BatchInterpolatedValue2DZeroWarp(data20, data1, 
					m, n, nx, offx, mx, wx, ny, offy, my,wy,
					(long)spline); 
				BatchInterpolatedGradX2DZeroWarp(data21, data1, 
					m, n, nx, offx, mx, wx, ny, offy, my,wy,
					(long)spline); 
				BatchInterpolatedGradY2DZeroWarp(data22, data1, 
					m, n, nx, offx, mx, wx, ny, offy, my,wy,
					(long)spline); 
			}
		}
		else
		{
			plhs[0] = mxCreateNumericArray(
					mxGetNumberOfElements(prhs[1]), dims, 
					mxSINGLE_CLASS, mxREAL);

			data2 = mxGetData(plhs[0]);
			if (ntot == 0) /* no warp */
			{
				BatchInterpolatedValue2DZero(data2, data1, m, n,
					 nx, offx, mx, ny, offy, my, 
					(long)spline); 
			}
			else
			{
				BatchInterpolatedValue2DZeroWarp(data2, data1, 
					m, n, nx, offx, mx, wx, ny, offy, my,wy,
					(long)spline); 
			}
		}
	}
}
// Create object from MATLAB struct variable.
// mx_shear is a struct containing the following fields:
// * fftPlanMany (array of forward FFT R2C plans, one multiplan per scale)
// * ifftPlanMany (array of inverse FFT C2R plans, one multiplan per scale)
// * fftPlanOne (one FFT R2C plan for a single image)
// * filter (cell array of filters, one cell element per scale)
bool ShearDictionary::loadFromMx(const mxArray* mx_shear, GPUmat* gm)
{
    if( hasData() )
    {
        mexErrMsgTxt( "Method ShearDictionary::loadFromMx() should only be called once" );
        return false;
    }

    // Get fields
    mxArray* mx_filter = mxGetField( mx_shear, 0, "filter" );
    mxArray* mx_fftPlanMany = mxGetField( mx_shear, 0, "fftPlanMany" );
    mxArray* mx_ifftPlanMany = mxGetField( mx_shear, 0, "ifftPlanMany" );
    mxArray* mx_fftPlanOne= mxGetField( mx_shear, 0, "fftPlanOne" );

    // Check size of first element
    mxArray* mx_filter_elem = mxGetCell(mx_filter, 0);

    // Get attributes
    GPUtype firstElem = gm->gputype.getGPUtype(mx_filter_elem);
    m_type = gm->gputype.getType(firstElem);
    if( m_type != gpuCFLOAT && m_type != gpuCDOUBLE )
    {
        mexErrMsgTxt("Filters should be complex of type GPUsingle or GPUdouble");
        return false;
    }
    m_nFilterLen = gm->gputype.getSize(firstElem)[0];

    // Check number of elements
    int numScales = (int)mxGetNumberOfElements(mx_filter);
    m_anNumDirections.resize(numScales);
    m_GPUtypeData.resize(numScales);

    // Check dimensions and get pointers
    for (int j = 0; j < numScales; j++)
    {
        mx_filter_elem = mxGetCell(mx_filter, (mwIndex)j);
        m_GPUtypeData[j] = gm->gputype.getGPUtype(mx_filter_elem);

        // Check filter type
        gpuTYPE_t type = gm->gputype.getType( m_GPUtypeData[j] );
        if( type != m_type )
        {
            mexErrMsgTxt("Filters should be of GPUsingle or GPUdouble and type should be consistent");
            return false;
        }

        // Check filter dimensions
        int numDims = gm->gputype.getNdims(m_GPUtypeData[j]);
        const int *dims = gm->gputype.getSize(m_GPUtypeData[j]);
        if (numDims>2)
            m_anNumDirections[j] = dims[2];
        else
            m_anNumDirections[j] = 1;
        if (dims[1] != (m_nFilterLen/2+1) || dims[0] != m_nFilterLen ) {
            mexErrMsgTxt("Filters should have same dimensions");
            return false;
        }
    }

    // Get pointers to FFT plans
    m_fftPlanMany = (cufftHandle*)mxGetData( mx_fftPlanMany );
    m_ifftPlanMany = (cufftHandle*)mxGetData( mx_ifftPlanMany );
    m_fftPlanOne = *(cufftHandle*)mxGetData( mx_fftPlanOne );

    // Set GPUmat environment
    m_gm = gm;

    return true;
}
Beispiel #26
0
/* read in input variables and run the algorithm */
void mexFunction(int nlhs, mxArray *plhs[], 
                 int nrhs, const mxArray *prhs[])                
{
 int orient, img, i, j, c, x, y; 
 mxArray *f;  
 
 c = 0; 
 /* about active basis */
 numOrient = ROUND(mxGetScalar(prhs[c++]));  
 locationShiftLimit = ROUND(mxGetScalar(prhs[c++]));    
 orientShiftLimit = ROUND(mxGetScalar(prhs[c++])); 
 subsample = ROUND(mxGetScalar(prhs[c++]));   
 numElement = ROUND(mxGetScalar(prhs[c++])); 
 /* about input images */
 numImage = ROUND(mxGetScalar(prhs[c++])); 
 sizex = ROUND(mxGetScalar(prhs[c++])); 
 sizey = ROUND(mxGetScalar(prhs[c++]));   
 SUM1map = mxCalloc(numImage*numOrient, sizeof(float*));  
 for (img=0; img<numImage; img++)
     for (orient=0; orient<numOrient; orient++)
      {  
       i = orient*numImage+img; 
       f = mxGetCell(prhs[c], i); 
       SUM1map[i] = mxGetPr(f);    
      }
 c++; 
 /* about Gabor filters */
 halfFilterSize = ROUND(mxGetScalar(prhs[c++]));     
 Correlation = mxCalloc(numOrient*numOrient, sizeof(double*));   
 for (orient=0; orient<numOrient; orient++)
     {  
       for (j=0; j<numOrient; j++)
        {
         f = mxGetCell(prhs[c], j*numOrient+orient); 
         Correlation[j*numOrient+orient] = mxGetPr(f); 
        }   
     }
 c++;  
 allSymbol = mxCalloc(numOrient, sizeof(double*));    
 for (orient=0; orient<numOrient; orient++)
     {  
       f = mxGetCell(prhs[c], orient); 
       allSymbol[orient] = mxGetPr(f);       
     }
 c++; 
 
 /* about exponential model */ 
 numStoredPoint = ROUND(mxGetScalar(prhs[c++])); 
 storedlambda = mxGetPr(prhs[c++]);   
 storedExpectation = mxGetPr(prhs[c++]);   
 storedLogZ = mxGetPr(prhs[c++]);  
 /* learned parameters of active basis */
 selectedOrient = mxGetPr(prhs[c++]);                 
 selectedx = mxGetPr(prhs[c++]);         
 selectedy = mxGetPr(prhs[c++]);   
 selectedlambda = mxGetPr(prhs[c++]);       
 selectedLogZ = mxGetPr(prhs[c++]);

 /* templates of images */
 commonTemplate = mxGetPr(prhs[c++]);
 deformedTemplate = mxCalloc(numImage, sizeof(float*)); 
 
 for (img=0; img<numImage; img++)
    {
        f = mxGetCell(prhs[c], img);
        deformedTemplate[img] = mxGetPr(f);  
     }
 c++; 
 
 for (x=1; x<=sizex; x++)
      for (y=1; y<=sizey; y++)
          commonTemplate[px(x, y, sizex, sizey)] = 0.; 
 
 for (img=0; img<numImage; img++)
 {
     for (x=1; x<=sizex; x++)
         for (y=1; y<=sizey; y++)
             deformedTemplate[img][px(x, y, sizex, sizey)] = 0.; 
 }
 
 /* MAX1 maps are smaller than SUM1 maps */
 sizexSubsample = floor((double)sizex/subsample); 
 sizeySubsample = floor((double)sizey/subsample); 
 
 /* run the shared sketch algorithm */
 StoreShift();  
 InitializeMAX1map(); 
 PursueElement(); 
 /* free matrices to avoid memory leak */  
 free_matrix(pooledMax1map, numOrient, sizexSubsample*sizeySubsample);  
 free_matrix(MAX1map, numImage*numOrient, sizexSubsample*sizeySubsample);  
 free_matrix(trackMap, numImage*numOrient, sizexSubsample*sizeySubsample);   
 free_matrix(xShift, numOrient, numShift); 
 free_matrix(yShift, numOrient, numShift); 
 free_matrix(orientShifted, numOrient, numShift);
}
Beispiel #27
0
void mcaMonitorEventHandler(struct event_handler_args arg)
{   union db_access_val *pBuf;
    struct mca_channel* PCHNL = (struct mca_channel*)arg.usr;
    double *myDblPr;
    chtype RequestType;
    int i,Cnt;
    mxArray* mymxArray;
    pBuf = (union db_access_val *)arg.dbr;
    
    //mexPrintf("MCA Monitor Event Handler Called\n");
    
    PCHNL->MonitorEventCount++;
    
    Cnt = ca_element_count(arg.chid);  
    RequestType = dbf_type_to_DBR(ca_field_type(arg.chid)); // Closest to the native 
    
    if(RequestType==DBR_STRING)
    {   if(Cnt==1)
        {   mxDestroyArray(PCHNL->CACHE); // clear mxArray that pointed to by PCHNL->CACHE
            PCHNL->CACHE = mxCreateString((char*)((pBuf)->strval)); // Create new array with current string value
            mexMakeArrayPersistent(PCHNL->CACHE);
        }
        else
        {   for(i=0;i<Cnt;i++)
            {   mymxArray = mxGetCell(PCHNL->CACHE,i);
                mxDestroyArray(mymxArray);
                mymxArray = mxCreateString(  (char*)   (&(pBuf->strval)+i)   );
                mexMakeArrayPersistent(mymxArray);
                mxSetCell(PCHNL->CACHE,i,mymxArray);
            }
        }
    }
    else
    {   myDblPr = mxGetPr(PCHNL->CACHE);
        
        switch(RequestType)
        {   case DBR_INT: // As defined in db_access.h DBR_INT = DBR_SHORT = 1
            for (i = 0; i<Cnt;i++)
                myDblPr[i]= (double)(*(&((pBuf)->intval)+i));
            break;    
            
            case DBR_FLOAT:
            for (i = 0; i<Cnt;i++)
                myDblPr[i]= (double)(*(&((pBuf)->fltval)+i));
            break;
                
            case DBR_ENUM:
            for (i = 0; i<Cnt;i++)
                myDblPr[i]= (double)(*(&((pBuf)->enmval)+i));
            break;
                
            case DBR_CHAR:
            for (i = 0; i<Cnt;i++)
                myDblPr[i]= (double)(*(&((pBuf)->charval)+i));
            break;
                    
            case DBR_LONG:
            for (i = 0; i<Cnt;i++)
                myDblPr[i]= (double)(*(&((pBuf)->longval)+i));
            break;
                    
            case DBR_DOUBLE:
            for (i = 0; i<Cnt;i++)
                myDblPr[i]= (double)(*(&((pBuf)->doubleval)+i));
            break;
        }
    }
    
    if(PCHNL->MonitorCBString)
    {   
        mexEvalString(PCHNL->MonitorCBString);
    }
}
void mexFunction(int nlhs, mxArray  *plhs[], 
                 int nrhs, const mxArray  *prhs[] )

{    mxArray  *blk_cell_pr;
     double   *A,  *B,  *AI, *BI, *blksize; 
     mwIndex  *irA, *jcA, *irB, *jcB;
     int      *cumblksize, *blknnz;
     int       mblk, isspA, isspB, iscmpA;

     mwIndex  subs[2];
     mwSize   nsubs=2; 
     int      m, n, n2, nsub, k, index, numblk, NZmax, type; 
     double   r2; 

/* CHECK FOR PROPER NUMBER OF ARGUMENTS */

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

/* CHECK THE DIMENSIONS */

    mblk = mxGetM(prhs[0]); 
    if (mblk > 1) { 
       mexErrMsgTxt("mexsvec: blk can have only 1 row."); }
    m = mxGetM(prhs[1]); 
    n = mxGetN(prhs[1]); 
    if (m != n) { 
       mexErrMsgTxt("mexsvec: matrix must be square."); }

    subs[0] = 0; subs[1] = 1;
    index = mxCalcSingleSubscript(prhs[0],nsubs,subs); 
    blk_cell_pr = mxGetCell(prhs[0],index);
    numblk  = mxGetN(blk_cell_pr);
    blksize = mxGetPr(blk_cell_pr); 
    if (numblk == 1) { 
       n2 = n*(n+1)/2; 
    } else { 
       cumblksize = mxCalloc(numblk+1,sizeof(int)); 
       blknnz = mxCalloc(numblk+1,sizeof(int)); 
       cumblksize[0] = 0; blknnz[0] = 0; 
       n = 0; n2 = 0; 
       for (k=0; k<numblk; ++k) {
           nsub = (int) blksize[k];
           n  += nsub; 
           n2 += nsub*(nsub+1)/2;  
           cumblksize[k+1] = n; 
           blknnz[k+1] = n2;  }
    }
    /***** assign pointers *****/
    A = mxGetPr(prhs[1]); 
    isspA = mxIsSparse(prhs[1]);
    iscmpA = mxIsComplex(prhs[1]);   
    if (isspA) {  irA = mxGetIr(prhs[1]); 
                  jcA = mxGetJc(prhs[1]); 
                  NZmax = mxGetNzmax(prhs[1]);  
    } else { 
       NZmax = n2; 
    }
    if (iscmpA) { AI = mxGetPi(prhs[1]); }
    if ((numblk > 1) & (!isspA)) {
       mexErrMsgTxt("mexsvec: matrix must be sparse for numblk > 1"); }
    if (nrhs > 2) { 
       if (mxGetM(prhs[2])>1) { isspB = (int)*mxGetPr(prhs[2]); }
       else if (NZmax < n2/2) { isspB = 1; }
       else                   { isspB = 0; } 
    } else {        
       if (NZmax < n2/2) { isspB = 1; }
       else              { isspB = 0; }
    } 
    if (nrhs > 3) { type = (int)*mxGetPr(prhs[3]); } 
    else          { type = 0; } 
    /***** create return argument *****/
    if (isspB) {
       if (iscmpA) { 
          plhs[0] = mxCreateSparse(n2,1,NZmax,mxCOMPLEX); 
       } else { 
          plhs[0] = mxCreateSparse(n2,1,NZmax,mxREAL); 
       }
       B = mxGetPr(plhs[0]);
       irB = mxGetIr(plhs[0]); 
       jcB = mxGetJc(plhs[0]); 
       jcB[0] = 0; 
    } else {
       if (iscmpA) { 
          plhs[0] = mxCreateDoubleMatrix(n2,1,mxCOMPLEX); 
       } else { 
          plhs[0] = mxCreateDoubleMatrix(n2,1,mxREAL); 
       }
       B = mxGetPr(plhs[0]);  
    } 
    if (iscmpA) { BI = mxGetPi(plhs[0]); }   
    /***** Do the computations in a subroutine *****/
    r2 = sqrt(2); 
    if (type == 0) { 
       if (iscmpA) {
         if (numblk == 1) { 
            svec1cmp(n,r2,A,irA,jcA,isspA,B,irB,jcB,isspB,AI,BI);  }
         else {
            svec2cmp(n,numblk,cumblksize,blknnz,r2,A,irA,jcA,isspA,B,irB,jcB,isspB,AI,BI); 
         }
       } else { 
         if (numblk == 1) { 
            svec1(n,r2,A,irA,jcA,isspA,B,irB,jcB,isspB);  }
         else {
            svec2(n,numblk,cumblksize,blknnz,r2,A,irA,jcA,isspA,B,irB,jcB,isspB); 
         }
       }
    } else {
       if (iscmpA) { 
         if (numblk == 1) { 
            svec3cmp(n,r2,A,irA,jcA,isspA,B,irB,jcB,isspB,AI,BI);  }
         else {
            svec4cmp(n,numblk,cumblksize,blknnz,r2,A,irA,jcA,isspA,B,irB,jcB,isspB,AI,BI); 
	 }
       } else {
         if (numblk == 1) { 
            svec3(n,r2,A,irA,jcA,isspA,B,irB,jcB,isspB);  }
         else {
            svec4(n,numblk,cumblksize,blknnz,r2,A,irA,jcA,isspA,B,irB,jcB,isspB); 
	 }
       }
    }
    return;
 }
// Sample factor vectors
// Function written from perspective of sampling user factor vectors with cross-topics
// Switch roles of user-item inputs to sample item factor vectors
void sampleTopicFactorVectors(uint32_t* items, double* resids, const mxArray* exampsByUser,
			      int KU, int KM, int numUsers, int numItems, double invSigmaSqd, 
			      ptrdiff_t numTopicFacs, double* LambdaU, double* muU, double* c, double* d, 
			      uint32_t* zU, uint32_t* zM){
   // Array of random number generators
   gsl_rng** rngs = getRngArray();  
 
   // Extract internals of jagged arrays
   uint32_t** userExamps;
   mwSize* userLens;
   unpackJagged(exampsByUser, &userExamps, &userLens, numUsers);

   ptrdiff_t numTopicFacsSqd = numTopicFacs*numTopicFacs;
   ptrdiff_t numTopicFacsTimesNumItems = numTopicFacs*numItems;
   ptrdiff_t numTopicFacsTimesNumUsers = numTopicFacs*numUsers;

   // BLAS constants
   char uplo[] = "U";
   char trans[] = "N";
   char diag[] = "N";
   ptrdiff_t oneInt = 1;
   double oneDbl = 1;
   double zeroDbl = 0;

   // Compute muBase = LambdaU*muU
   double* muBase = mxMalloc(numTopicFacs*sizeof(*muBase));
   dsymv(uplo, &numTopicFacs, &oneDbl, LambdaU, &numTopicFacs, muU, &oneInt, &zeroDbl, muBase, &oneInt);

   // Allocate memory for new mean and precision parameters
   double** muNew[MAX_NUM_THREADS];
   double** LambdaNew[MAX_NUM_THREADS];
   for(int thread = 0; thread < MAX_NUM_THREADS; thread++){
      muNew[thread] = mxMalloc(KM*sizeof(**muNew));
      LambdaNew[thread] = mxMalloc(KM*sizeof(**LambdaNew));
      for(int i = 0; i < KM; i++){
	 muNew[thread][i] = mxMalloc(numTopicFacs*sizeof(***muNew));
	 LambdaNew[thread][i] = mxMalloc(numTopicFacsSqd*sizeof(***LambdaNew));
      }
   }

#pragma omp parallel for
   for(int u = 0; u < numUsers; u++){
      int thread = omp_get_thread_num();
      for(int i = 0; i < KM; i++){
	 // Initialize new mean to muBase
	 dcopy(&numTopicFacs, muBase, &oneInt, muNew[thread][i], &oneInt);
	 // Initialize new precision to LambdaU
	 dcopy(&numTopicFacsSqd, LambdaU, &oneInt, LambdaNew[thread][i], &oneInt);
      }

      // Iterate over user's examples
      mxArray* exampsArray = mxGetCell(exampsByUser, u);
      mwSize len = mxGetN(exampsArray);
      uint32_t* examps = (uint32_t*) mxGetData(exampsArray);
      for(int j = 0; j < len; j++){
	 uint32_t e = examps[j]-1;
	 int m = items[e]-1;
	 int userTop = zU[e]-1;
	 int itemTop = zM[e]-1;

	 // Item vector for this rated item
	 double* dVec = d + m*numTopicFacs + userTop*numTopicFacsTimesNumItems;

	 // Compute posterior sufficient statistics for factor vector
	 // Add resid * dVec/sigmaSqd to muNew
	 double resid = resids[e];
	 resid *= invSigmaSqd;
	 daxpy(&numTopicFacs, &resid, dVec, &oneInt, muNew[thread][itemTop], &oneInt);

	 // Add (dVec * dVec^t)/sigmaSqd to LambdaNew
	 // Exploit symmetric structure of LambdaNew
	 dsyr(uplo, &numTopicFacs, &invSigmaSqd, dVec, &oneInt, LambdaNew[thread][itemTop], 
	      &numTopicFacs);
      }
      
      for(int i = 0; i < KM; i++){
	 // Compute upper Cholesky factor of LambdaNew
	 ptrdiff_t info;
	 dpotrf(uplo, &numTopicFacs, LambdaNew[thread][i], &numTopicFacs, &info);
	 
	 // Solve for (LambdaNew)^-1*muNew using Cholesky factor
	 dpotrs(uplo, &numTopicFacs, &oneInt, LambdaNew[thread][i], &numTopicFacs, muNew[thread][i], 
		&numTopicFacs, &info);
	 
	 // Sample vector of N(0,1) variables
	 gsl_rng* rng = rngs[thread];
	 double* cVec = c + u*numTopicFacs + i*numTopicFacsTimesNumUsers;
	 for(int f = 0; f < numTopicFacs; f++)
	    cVec[f] = gsl_ran_gaussian(rng, 1);
	 
	 // Solve for (chol(LambdaNew,'U'))^-1*N(0,1)
	 dtrtrs(uplo, trans, diag, &numTopicFacs, &oneInt, LambdaNew[thread][i], 
		&numTopicFacs, cVec, &numTopicFacs, &info);
	 
	 // Add muNew to aVec
	 daxpy(&numTopicFacs, &oneDbl, muNew[thread][i], &oneInt, cVec, &oneInt);
      }
   }
   // Clean up
   mxFree(userExamps);
   mxFree(userLens);
   mxFree(muBase);
   for(int thread = 0; thread < MAX_NUM_THREADS; thread++){
      for(int i = 0; i < KM; i++){
	 mxFree(muNew[thread][i]);
	 mxFree(LambdaNew[thread][i]);
      }
      mxFree(muNew[thread]);
      mxFree(LambdaNew[thread]);
   }
}
Beispiel #30
0
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
	
// 	printf("start of file \n");
	
	//	Get array_sizes
	const mxArray* mx_array_sizes = mexGetVariablePtr("global", "array_sizes");
	if (mx_array_sizes == NULL) {
		mexErrMsgTxt("array_sizes not defined");
	}
	unsigned array_sizes = (unsigned)mxGetScalar(mx_array_sizes);
	
	//	Get iteration
	const mxArray* mx_iteration = mexGetVariablePtr("caller", "iteration");
	if (mx_iteration == NULL) {
		mexErrMsgTxt("iteration not defined");
	}
	double iteration = mxGetScalar(mx_iteration);
	
	//	Get protection_time
	const mxArray* mx_protection_time = mexGetVariablePtr("caller", "protection_time");
	if (mx_protection_time == NULL) {
		mexErrMsgTxt("protection_time not defined");
	}
	double protection_time = mxGetScalar(mx_protection_time);
	
	//	Get join_probability
	const mxArray* mx_join_probability = mexGetVariablePtr("caller", "join_probability");
	if (mx_join_probability == NULL) {
		mexErrMsgTxt("join_probability not defined");
	}
	double join_probability = mxGetScalar(mx_join_probability);
	
	//	Get threshold_join_nodes
	const mxArray* mx_threshold_join_nodes = mexGetVariablePtr("caller", "threshold_join_nodes");
	if (mx_threshold_join_nodes == NULL) {
		mexErrMsgTxt("threshold_join_nodes not defined");
	}
	double threshold_join_nodes = mxGetScalar(mx_threshold_join_nodes);
	
	//	Get time
	const mxArray* mx_time = mexGetVariablePtr("global", "time");
	if (mx_time == NULL) {
		mexErrMsgTxt("time not defined");
	}
	double time = mxGetScalar(mx_time);
	
	unsigned width_cell_store = mxGetN(prhs[1]);
	unsigned no_cells = mxGetM(prhs[2]);
	unsigned no_FEM_elements = mxGetM(prhs[5]);
	unsigned length_FEM_node_positions = mxGetM(prhs[6]);
	
	double* initial_cell_store = mxGetPr(prhs[1]);
	double* initial_cells_per_node = mxGetPr(prhs[3]);
	double* initial_Dpp = mxGetPr(prhs[4]);
	double* initial_FEM_elements = mxGetPr(prhs[5]);
	double* initial_previous_FEM_node_positions = mxGetPr(prhs[6]);
	double* initial_node_positions = mxGetPr(prhs[7]);
	double* initial_time_nodes_created = mxGetPr(prhs[8]);
	
	plhs[0] = mxCreateCellMatrix(no_cells, 1);
	plhs[1] = mxCreateDoubleMatrix(array_sizes, width_cell_store, mxREAL);
	plhs[2] = mxCreateCellMatrix(no_cells, 1);
	plhs[3] = mxCreateDoubleMatrix(array_sizes, 1, mxREAL);
	plhs[4] = mxCreateDoubleMatrix(length_FEM_node_positions, 1, mxREAL);
	plhs[5] = mxCreateDoubleMatrix(no_FEM_elements, 3, mxREAL);
	plhs[6] = mxCreateDoubleMatrix(length_FEM_node_positions, 2, mxREAL);
	plhs[7] = mxCreateDoubleMatrix(array_sizes, 2, mxREAL);
	plhs[8] = mxCreateDoubleMatrix(array_sizes, 1, mxREAL);
	plhs[9] = mxCreateDoubleMatrix(1, 1, mxREAL);
	
	double* final_cell_store = mxGetPr(plhs[1]);
	double* final_cells_per_node = mxGetPr(plhs[3]);
	double* final_Dpp = mxGetPr(plhs[4]);
	double* final_FEM_elements = mxGetPr(plhs[5]);
	double* final_previous_FEM_node_positions = mxGetPr(plhs[6]);
	double* final_node_positions = mxGetPr(plhs[7]);
	double* final_time_nodes_created = mxGetPr(plhs[8]);
	double* no_join_nodes_this_iteration = mxGetPr(plhs[9]);
	
	*no_join_nodes_this_iteration = 0;
	
	// set output matrices equal to input matrices
	for(unsigned current_node=0;current_node<array_sizes;current_node++){
		final_cells_per_node[current_node] = initial_cells_per_node[current_node];
		final_time_nodes_created[current_node] = initial_time_nodes_created[current_node];
		for(unsigned dim=0;dim<2;dim++){
			final_node_positions[current_node+array_sizes*dim] = initial_node_positions[current_node+array_sizes*dim];
		}
		for(unsigned i=0;i<width_cell_store;i++){
			final_cell_store[current_node+i*array_sizes] = initial_cell_store[current_node+i*array_sizes];
		}
	}
	
	for(unsigned current_element=0;current_element<no_FEM_elements;current_element++){
		for(unsigned i=0;i<3;i++){
			final_FEM_elements[current_element+no_FEM_elements*i] =
					  initial_FEM_elements[current_element+no_FEM_elements*i];
		}
	}
	
	for(unsigned current_FEM_node=0;current_FEM_node<length_FEM_node_positions;current_FEM_node++){
		final_Dpp[current_FEM_node] = initial_Dpp[current_FEM_node];
		for(unsigned dim=0;dim<2;dim++){
			final_previous_FEM_node_positions[current_FEM_node+length_FEM_node_positions*dim] =
					  initial_previous_FEM_node_positions[current_FEM_node+length_FEM_node_positions*dim];
		}
	}
	
	// set output cells equal to input cells
	for(unsigned current_cell=0; current_cell<no_cells; current_cell++) {
		
		mxArray* mx_initial_cell_nodes = mxGetCell(prhs[2], current_cell);
		
		unsigned no_cell_nodes = mxGetN(mx_initial_cell_nodes);
		
		double* initial_cell_nodes = mxGetPr(mx_initial_cell_nodes);
		
		mxArray* mx_final_cell_nodes = mxCreateDoubleMatrix(1, no_cell_nodes, mxREAL);
		double* final_cell_nodes = mxGetPr(mx_final_cell_nodes);
		
		mxArray* mx_initial_cell_elements = mxGetCell(prhs[0], current_cell);
		double* initial_cell_elements = mxGetPr(mx_initial_cell_elements);
		
		mxArray* mx_final_cell_elements = mxCreateDoubleMatrix(1, no_cell_nodes, mxREAL);
		double* final_cell_elements = mxGetPr(mx_final_cell_elements);
		
		for(unsigned i=0; i<no_cell_nodes;i++){
			final_cell_nodes[i] = initial_cell_nodes[i];
			final_cell_elements[i] = initial_cell_elements[i];
		}
		
		mxSetCell(plhs[2], current_cell, mx_final_cell_nodes);
		mxSetCell(plhs[0], current_cell, mx_final_cell_elements);
		
	}
	
	bool join_logical;
	
	// loop over all cells
	for(unsigned current_cell_ci=0; current_cell_ci<no_cells; current_cell_ci++) {
		
		join_logical = false;
		
// 		printf("start of main loop \n");
		
		unsigned current_cell_mi = current_cell_ci+1;
		
		mxArray* mx_cell_nodes = mxGetCell(plhs[2], current_cell_ci);
		double* cell_nodes = mxGetPr(mx_cell_nodes);
		
		unsigned no_cell_nodes = mxGetN(mx_cell_nodes);
		
		// only proceed if there are more than 3 cell nodes
		if(no_cell_nodes > 3){
			
			// loop over the nodes of the current cell
			for(unsigned current_node_local=0; current_node_local<no_cell_nodes; current_node_local++) {
				
				double rand_number = rand()/((double)RAND_MAX);
				
				// only proceed with p(join_probability)
				if(rand_number < join_probability){
					
					// find current node and clockwise node in matlab and c indicies
					unsigned current_node_global_mi = (unsigned)cell_nodes[current_node_local];
					unsigned current_node_global_ci = current_node_global_mi-1;
					
					unsigned clockwise_node_local = (current_node_local+1)%no_cell_nodes;
					
					unsigned clockwise_node_global_mi = (unsigned)cell_nodes[clockwise_node_local];
					unsigned clockwise_node_global_ci = clockwise_node_global_mi - 1;
					
					// extract the positions of the current node and clockwise node from the node positions matrix
					double current_node_position[2], clockwise_node_position[2];
					
					for(unsigned dim=0;dim<2;dim++) {
						
						current_node_position[dim] = final_node_positions[current_node_global_ci + dim*array_sizes];
						clockwise_node_position[dim] = final_node_positions[clockwise_node_global_ci + dim*array_sizes];
					}
					
					// find the current edge length
					double current_edge_length = findStraightLineDistanceBetweenTwoNodes(current_node_position,
							  clockwise_node_position);
					
					// only proceed if edge length is less than threshold, and nodes have not been created very
					// recently
					if(current_edge_length < threshold_join_nodes &&
							  (time-final_time_nodes_created[current_node_global_ci])>protection_time &&
							  (time-final_time_nodes_created[clockwise_node_global_ci])>protection_time){
						
// 						printf("hello \n");
						
						// look for a cell that shares the edge - we need this for a T1 swap
						bool cell_with_same_edge_found = false;
						int cell_with_same_edge_mi = -1;
						
						unsigned counter_1 = 0;
						// loop over all cells containing current_node_global
						for(unsigned i=0;i<final_cells_per_node[current_node_global_ci];i++){
							
							unsigned temp_cell_1_mi = (unsigned)final_cell_store[current_node_global_ci + i*array_sizes];
							
							// if not current_cell, loop over all cells containing clockwise_node_global
							if(temp_cell_1_mi != current_cell_mi && !cell_with_same_edge_found){
								for(unsigned j=0;j<final_cells_per_node[clockwise_node_global_ci];j++){
									
									unsigned temp_cell_2_mi = (unsigned)final_cell_store[clockwise_node_global_ci + j*array_sizes];
									
									// if cell containing clockwise_node_global is also a cell containing current_node_global,
									// but not current_cell, then it is cell_with_same_edge;
									if(temp_cell_2_mi == temp_cell_1_mi){
										cell_with_same_edge_mi = temp_cell_1_mi;
										cell_with_same_edge_found = true;
										break;
									}
								}
							}
							
						}
						
						if(!cell_with_same_edge_found){
							
							join_logical = true;
							(*no_join_nodes_this_iteration)++;
							
// 							printf("doing a join \n");
							
							double new_node_position[2];
							for(unsigned dim=0;dim<2;dim++) {
								new_node_position[dim] = (current_node_position[dim] +
										  clockwise_node_position[dim])/2;
							}
							
							// find two unused nodes to put new nodes in
							unsigned new_node_ci = 0;
							while(final_cells_per_node[new_node_ci]>0){
								new_node_ci++;
							}
							unsigned new_node_mi = new_node_ci+1;
							
							assert(new_node_mi <= array_sizes);
							
							// store new node position
							for(unsigned dim=0;dim<2;dim++){
								final_node_positions[new_node_ci+dim*array_sizes] =
										  new_node_position[dim];
							}
							
							// set time new nodes created to current time
							final_time_nodes_created[new_node_ci] = time;
							
							// edit current cell nodes to contain new node instead of previous two nodes
							mxArray* mx_cell_nodes_edited = mxCreateDoubleMatrix(1, no_cell_nodes-1, mxREAL);
							double* cell_nodes_edited = mxGetPr(mx_cell_nodes_edited);
							
							int temp_counter = -1;
							for(unsigned temp_current_node_local=0;temp_current_node_local<no_cell_nodes;temp_current_node_local++){
								
								unsigned temp_current_node_global_mi = (unsigned)cell_nodes[temp_current_node_local];
								
								if(temp_current_node_global_mi==current_node_global_mi){
									temp_counter++;
									cell_nodes_edited[temp_counter]=new_node_mi;
								}
								else if(temp_current_node_global_mi==clockwise_node_global_mi){}
								else{
									temp_counter++;
									cell_nodes_edited[temp_counter]=temp_current_node_global_mi;
								}
							}
							mxSetCell(plhs[2], current_cell_ci, mx_cell_nodes_edited);
							
// 							printf("edited current cell \n");
							
							final_cells_per_node[new_node_ci] = 1;
							final_cell_store[new_node_ci] = current_cell_mi;
							
							if(final_cells_per_node[current_node_global_ci] > 1.1){
								
								for(unsigned i=0;i<final_cells_per_node[current_node_global_ci];i++){
									
									unsigned temp_cell_mi = (unsigned)final_cell_store[current_node_global_ci + i*array_sizes];
									
									if(temp_cell_mi!=current_cell_mi){
										
										unsigned temp_cell_ci = temp_cell_mi-1;
										
										mxArray* mx_cell_nodes_temp_cell = mxGetCell(plhs[2], temp_cell_ci);
										double* cell_nodes_temp_cell = mxGetPr(mx_cell_nodes_temp_cell);
										unsigned no_cell_nodes_temp_cell = mxGetN(mx_cell_nodes_temp_cell);
										
										mxArray* mx_cell_nodes_temp_cell_edited = mxCreateDoubleMatrix(1, no_cell_nodes_temp_cell, mxREAL);
										double* cell_nodes_temp_cell_edited = mxGetPr(mx_cell_nodes_temp_cell_edited);
										
										for(unsigned temp_current_node_local=0;temp_current_node_local<no_cell_nodes_temp_cell;temp_current_node_local++){
											
											unsigned temp_current_node_global_mi = (unsigned)cell_nodes_temp_cell[temp_current_node_local];
											
											if(temp_current_node_global_mi==current_node_global_mi){
												cell_nodes_temp_cell_edited[temp_current_node_local] = new_node_mi;
											}
											else{
												cell_nodes_temp_cell_edited[temp_current_node_local] = temp_current_node_global_mi;
											}
										}
										
										mxSetCell(plhs[2], temp_cell_ci, mx_cell_nodes_temp_cell_edited);
										
										final_cells_per_node[new_node_ci]++;
										unsigned matrix_index = (unsigned)(new_node_ci+array_sizes*(final_cells_per_node[new_node_ci]-1));
										final_cell_store[matrix_index] = temp_cell_mi;
									}
								}
// 								printf("edited cells with node 1 \n");
							}
							
							if(final_cells_per_node[clockwise_node_global_ci] > 1.1){
								
								for(unsigned i=0;i<final_cells_per_node[clockwise_node_global_ci];i++){
									
									unsigned temp_cell_mi = (unsigned)final_cell_store[clockwise_node_global_ci + i*array_sizes];
									
									if(temp_cell_mi!=current_cell_mi){
										
										unsigned temp_cell_ci = temp_cell_mi-1;
										
										// edit stretch cell 1 by adding in two new nodes in place of current node global
										mxArray* mx_cell_nodes_temp_cell = mxGetCell(plhs[2], temp_cell_ci);
										double* cell_nodes_temp_cell = mxGetPr(mx_cell_nodes_temp_cell);
										unsigned no_cell_nodes_temp_cell = mxGetN(mx_cell_nodes_temp_cell);
										
										mxArray* mx_cell_nodes_temp_cell_edited = mxCreateDoubleMatrix(1, no_cell_nodes_temp_cell, mxREAL);
										double* cell_nodes_temp_cell_edited = mxGetPr(mx_cell_nodes_temp_cell_edited);
										
										for(unsigned temp_current_node_local=0;temp_current_node_local<no_cell_nodes_temp_cell;temp_current_node_local++){
											
											unsigned temp_current_node_global_mi = (unsigned)cell_nodes_temp_cell[temp_current_node_local];
											
											if(temp_current_node_global_mi==clockwise_node_global_mi){
												cell_nodes_temp_cell_edited[temp_current_node_local] = new_node_mi;
											}
											else{
												cell_nodes_temp_cell_edited[temp_current_node_local] = temp_current_node_global_mi;
											}
										}
										
										mxSetCell(plhs[2], temp_cell_ci, mx_cell_nodes_temp_cell_edited);
										
										// add stretch cell 1 to cells_per_node and cell_store for new_node and new_node_2
										final_cells_per_node[new_node_ci]++;
										unsigned matrix_index = (unsigned)(new_node_ci+array_sizes*(final_cells_per_node[new_node_ci]-1));
										final_cell_store[matrix_index] = temp_cell_mi;
										
									}
								}
								printf("edited cells with node 2 \n");
								
							}
							
							// reset cells per node and cell store for current_node_global and clockwise_node_global.
							// they should no longer be part of any cells, unless something has gone horribly wrong.
							final_cells_per_node[current_node_global_ci] = 0;
							final_cells_per_node[clockwise_node_global_ci] = 0;
							
							for(unsigned i=0;i<width_cell_store;i++){
								final_cell_store[current_node_global_ci+i*array_sizes] = 0;
								final_cell_store[clockwise_node_global_ci+i*array_sizes] = 0;
							}
							
							for(unsigned dim=0;dim<2;dim++){
								final_node_positions[current_node_global_ci+dim*array_sizes] = 0;
								final_node_positions[clockwise_node_global_ci+dim*array_sizes] = 0;
							}
						}
					}
				}
				if(join_logical){break;}
			}
		}
		if(join_logical){break;}
	}
}