Example #1
0
/* 03-sep-2008*/
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
    
    char * filename;
    FILE * fid;
    int buflen;
    unsigned int packetSize;
    short *outw;
    short type, upperbyte,channel,unit,nwf, nwords,wf[64];
    int header[64],freq,ndsp,nevents,nslow,timestamp,dim[2],j,EventCount;
    unsigned long counter,SpikeCount;
    double *out,*wfs;
    int ncounts[512],en,st;
    char Trodalness;
    int p = 0;
 /* Get filename */
    buflen = mxGetM(prhs[0]) * mxGetN(prhs[0])+1;
    filename = mxCalloc(buflen, sizeof(char));
    mxGetString(prhs[0], filename, buflen);
    wfs = mxGetPr(prhs[1]);
    
    fid = fopen(filename,"rb");
    if (fid == NULL)
    {
        mexPrintf("PLX File not found\n");
        return;
    }
    fread(&header,4,64,fid);
    freq = header[34];
    ndsp = header[35];
    nevents = header[36];
    nslow = header[37];
    packetSize = header[38];
    fseek(fid,5200,SEEK_CUR);
    fread(&ncounts,4,512,fid);
    EventCount = 0;
    for(counter=0;counter<512;counter++)
        EventCount += ncounts[counter];
    
    fseek(fid,0,SEEK_END);
    en = ftell(fid);
    
    fseek(fid,200,SEEK_SET);
    fread(&Trodalness,1,1,fid);
    
    fseek(fid,1020*ndsp + 296*nevents + 296*nslow+7504,SEEK_SET);
    st = ftell(fid);
    
    SpikeCount = 0;
    if (wfs[0] >= 2)
    {
        while (ftell(fid)!=en && !feof(fid))
        {
            fread(&type,2,1,fid);
            fread(&upperbyte,2,1,fid);
            fread(&timestamp,4,1,fid);
            fread(&channel,2,1,fid);
            fread(&unit,2,1,fid);
            fread(&nwf,2,1,fid);
            if (feof(fid))
                break;
            fread(&nwords,2,1,fid);
            
            if (nwords > 0)
                fread(&wf,2,nwords,fid);
            if (type==1 && (channel < 1 || channel > 28 || unit!=0))
                SpikeCount++;
        }
    }
    else
        SpikeCount = (en-st-EventCount*16)/(16+2*packetSize);
    fseek(fid,1020*ndsp + 296*nevents + 296*nslow+7504,SEEK_SET);
    
    
    plhs[0] = mxCreateDoubleMatrix(SpikeCount/Trodalness,3,mxREAL);
    out = mxGetPr(plhs[0]);
    
    dim[0] = SpikeCount/Trodalness;
    dim[1] = packetSize*Trodalness;
    
    if (wfs[0] ==1 || wfs[0] ==3)
    {
        plhs[1] = mxCreateNumericArray(2, dim, mxINT16_CLASS, mxREAL);
        outw = mxGetData(plhs[1]);
    }
    
    counter = 0;
    p = 0;
    while (ftell(fid)!=en && !feof(fid))
    {
        fread(&type,2,1,fid);
        fread(&upperbyte,2,1,fid);
        fread(&timestamp,4,1,fid);
        fread(&channel,2,1,fid);
        fread(&unit,2,1,fid);
        fread(&nwf,2,1,fid);
        if (feof(fid))
            break;
        fread(&nwords,2,1,fid);
        if (nwords > 0)
            fread(&wf,2,nwords,fid);
        if (type == 1 &&(wfs[0]<2 || unit!= 0 || channel>28))
        {
            if (Trodalness==1)
            {
                out[counter             ]=(double)channel;
                out[counter+  SpikeCount]=(double)unit;
                out[counter+2*SpikeCount]=(double)(timestamp)/freq;
                if ((wfs[0] ==1 || wfs[0] ==3) && nwords > 0)
                {
                    for (j=0;j<nwords;j++)
                        outw[counter+j*SpikeCount] = wf[j];
                }
                counter++;
            }
            else if(Trodalness==4)
            {
                if (counter%4==0)
                {
                    if(channel!=29)
                        out[counter/4             ]=(double)channel;
                    else
                        out[counter/4             ]=32.0;
                    out[counter/4+  SpikeCount/4]=(double)unit;
                    out[counter/4+2*SpikeCount/4]=(double)(timestamp)/freq;
                }
                if ((wfs[0] ==1 || wfs[0] ==3) && nwords > 0)
                {
                    for (j=0;j<nwords;j++)
                        outw[counter/4+(j+packetSize*((channel-1)%4))*SpikeCount/4] = wf[j];
                }
                
                counter++;
                
            }
        }
    }
    fclose(fid);

}
Example #2
0
// To run SAXParser in MATLAB: 
// [v, ds, ws, es, ews, des, ss, ess, ns, ens] = SAXParser('')
void MATProcedure(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {


    // pass the inverted index back to matlab
    // here we have to individually pass all the data from the maps into mxArrays
    
    // create the vocab array
    //int vocab_size = InvertedIndex::instance()->getVocabSize();
    
    map<string, int>* vocab = &(InvertedIndex::instance()->vocab);
    int vocab_size = InvertedIndex::instance()->vocab.size();

    //int i = 0;
    mwSize vsize = static_cast<mwSize>(vocab_size);
    plhs[0] = mxCreateCellArray(1, &vsize);
    for(map<string, int>::iterator it = vocab->begin(); it != vocab->end(); it++) {
      mxSetCell(plhs[0], (*it).second - 1, mxCreateString((*it).first.c_str()));
    }
    
    // create WS and DS arrays
    // WS, DS is size 1 x n where n is the number of word tokens. 
    // The word stream WS contains word indices in order of occurence with WS=0 
    // representing the end-of-sentence-end marker. 
    // The document indices DS contains all document indices and max(DS) = D = number of documents
    // they should be double-precision vectors
    
    int numwords = InvertedIndex::instance()->docs.size();
    plhs[1] = mxCreateDoubleMatrix(numwords, 1, mxREAL);
    plhs[2] = mxCreateDoubleMatrix(numwords, 1, mxREAL); 
    double *Z = mxGetPr(plhs[1]);
    double *D = mxGetPr(plhs[2]);
    
    for(multimap<int, int>::const_iterator it = InvertedIndex::instance()->docs.begin();
	it != InvertedIndex::instance()->docs.end();
	it++) {
      //cout << (*it).first << " " << (*it).second << "\n";
      *(Z++) = (*it).first;
      *(D++) = (*it).second;
    } 
    
    // Create sparse arrays for entities
    int rows, cols, nzmax;
    rows = InvertedIndex::instance()->entities.highest(); // highest index in entities;
    cols = vocab_size;
    nzmax = InvertedIndex::instance()->entities.size();
    
    multimap<int, int> rev = InvertedIndex::instance()->entities.reverseMap();
    
    plhs[3] = createMATSparseMatrix(rows, cols, nzmax, rev.begin(), rev.end());
    
    
  // create an array for entity_weights
    mwSize dims[2];
    dims[1] = 1;
    dims[0] = InvertedIndex::instance()->entities.highest();
    plhs[4] = mxCreateNumericArray(2, dims, mxINT32_CLASS, mxREAL);
    int *W = (int*)mxGetData(plhs[4]);
    for(multimap<int,int>::const_iterator it = InvertedIndex::instance()->entity_weights.begin(); 
	it != InvertedIndex::instance()->entity_weights.end();
	it++) {
      W[(*it).first-1] = (*it).second;
    //cout << (*it).second << " " << W[(*it).first] << "\n";
    }
    
    
    // create a sparse matrix for doc_entities
    rows = InvertedIndex::instance()->docs.highest();
    cols = InvertedIndex::instance()->entities.highest();
    nzmax = InvertedIndex::instance()->doc_entities.size();
    rev = InvertedIndex::instance()->doc_entities.reverseMap();
    plhs[5] = createMATSparseMatrix(rows, cols, nzmax, rev.begin(), rev.end());
    
    // crate a sparse matrix for syns
    rows = InvertedIndex::instance()->syns.highest();
    cols = vocab_size;
    nzmax = InvertedIndex::instance()->syns.size();
    rev = InvertedIndex::instance()->syns.reverseMap();
    plhs[6] = createMATSparseMatrix(rows, cols, nzmax, rev.begin(), rev.end());
    
    // create a sparse matrix for entity_syn 
    rows = InvertedIndex::instance()->entities.highest();
    cols = InvertedIndex::instance()->syns.highest();
    nzmax = InvertedIndex::instance()->entity_syns.size();
    rev = InvertedIndex::instance()->entity_syns.reverseMap();
    plhs[7] = createMATSparseMatrix(rows, cols, nzmax, rev.begin(), rev.end());

    // crate a sparse matrix for names
    rows = InvertedIndex::instance()->names.highest();
    cols = vocab_size;
    nzmax = InvertedIndex::instance()->names.size();
    rev = InvertedIndex::instance()->names.reverseMap();
    plhs[8] = createMATSparseMatrix(rows, cols, nzmax, rev.begin(), rev.end());
    
    // create a sparse matrix for entity_names
    rows = InvertedIndex::instance()->entities.highest();
    cols = InvertedIndex::instance()->names.highest();
    nzmax = InvertedIndex::instance()->entity_names.size();
    rev = InvertedIndex::instance()->entity_names.reverseMap();
    plhs[9] = createMATSparseMatrix(rows, cols, nzmax, rev.begin(), rev.end());
    
}
/* The matlab mex function */
void mexFunction( int nlhs, mxArray *plhs[],
                  int nrhs, const mxArray *prhs[] )
{
    /* Ox and Oy are the grid points */
    /* Zo is the input image */
    /* Zi is the transformed image */
    /* dx and dy are the spacing of the b-spline knots */
    double *Ox,*Oy, *dxa, *dya, *Iout;
    mxArray *matlabCallOut[1]={0};
    mxArray *matlabCallIn[1]={0};
    double *Nthreadsd;
    int Nthreads;





    /* double pointer array to store all needed function variables) */
    double ***ThreadArgs;
    double **ThreadArgs1;
    
	/* Handles to the worker threads */
		ThreadHANDLE *ThreadList;
	    
    /* ID of Threads */
    double **ThreadID;              
    double *ThreadID1;
    


    /* Size of input image */
    double *Isize_d;
    mwSize dims[3];
    
    
    /* Size of grid */
    mwSize  Osizex, Osizey;
    double Osize_d[2]={0,0};
    
    /* B-spline variablesl */
    double u,v;
    int u_index=0; 
    int v_index=0;
    double *Bu, *Bv, *Bdu, *Bdv;

    /* Loop variable  */
    int i;
    
    /* X,Y coordinates of current pixel */
    int x,y;
    /* Grid distance */
    int dx,dy; 
    
  /* Check for proper number of arguments. */
  if(nrhs!=5) {
    mexErrMsgTxt("Five inputs are required.");
  }
  
    /* Get the sizes of the grid */
  Osizex = (mwSize)mxGetM(prhs[0]);  
  Osizey = (mwSize)mxGetN(prhs[0]);
    
  /* Assign pointers to each input. */
  Ox=mxGetPr(prhs[0]);
  Oy=mxGetPr(prhs[1]);
  Isize_d=mxGetPr(prhs[2]);
  dxa=mxGetPr(prhs[3]);
  dya=mxGetPr(prhs[4]);
  
  /* Create image matrix for the return arguments with the size of input image  */  
  dims[0]=(mwSize)Isize_d[0]; dims[1]=(mwSize)Isize_d[1];
  plhs[0] = mxCreateNumericArray(2, dims, mxDOUBLE_CLASS, mxREAL);
  
 




 
  /* Get the spacing of the uniform b-spline grid */
  dx=(int)dxa[0]; dy=(int)dya[0];
  
  /* Get number of allowed threads */
  mexCallMATLAB(1, matlabCallOut, 0, matlabCallIn, "maxNumCompThreads");
  Nthreadsd=mxGetPr(matlabCallOut[0]);
  Nthreads=(int)Nthreadsd[0];
    /* Reserve room for handles of threads in ThreadList  */
		ThreadList = (ThreadHANDLE*)malloc(Nthreads* sizeof( ThreadHANDLE ));
	
  ThreadID = (double **)malloc( Nthreads* sizeof(double *) );
  ThreadArgs = (double ***)malloc( Nthreads* sizeof(double **) );

   
  /* Assign pointer to output. */
  Iout = mxGetPr(plhs[0]);


  
  /*  Make polynomial look up tables   */
  Bu=malloc(dx*4*sizeof(double));
  Bv=malloc(dy*4*sizeof(double));
  Bdu=malloc(dx*4*sizeof(double));
  Bdv=malloc(dy*4*sizeof(double));
  for (x=0; x<dx; x++)
  {
    u=(x/(double)dx)-floor(x/(double)dx);
    Bu[mindex2(0,x,4)] = BsplineCoefficient(u,0);
    Bu[mindex2(1,x,4)] = BsplineCoefficient(u,1);
    Bu[mindex2(2,x,4)] = BsplineCoefficient(u,2);
    Bu[mindex2(3,x,4)] = BsplineCoefficient(u,3);
    Bdu[mindex2(0,x,4)] = BsplineCoefficientDerivative(u,0)/dxa[0];
    Bdu[mindex2(1,x,4)] = BsplineCoefficientDerivative(u,1)/dxa[0];
    Bdu[mindex2(2,x,4)] = BsplineCoefficientDerivative(u,2)/dxa[0];
    Bdu[mindex2(3,x,4)] = BsplineCoefficientDerivative(u,3)/dxa[0];
  }
  
  for (y=0; y<dy; y++)
  {
    v=(y/(double)dy)-floor(y/(double)dy);
    Bv[mindex2(0,y,4)] = BsplineCoefficient(v,0);
    Bv[mindex2(1,y,4)] = BsplineCoefficient(v,1);
    Bv[mindex2(2,y,4)] = BsplineCoefficient(v,2);
    Bv[mindex2(3,y,4)] = BsplineCoefficient(v,3);
    Bdv[mindex2(0,y,4)] = BsplineCoefficientDerivative(v,0)/dya[0];
    Bdv[mindex2(1,y,4)] = BsplineCoefficientDerivative(v,1)/dya[0];
    Bdv[mindex2(2,y,4)] = BsplineCoefficientDerivative(v,2)/dya[0];
    Bdv[mindex2(3,y,4)] = BsplineCoefficientDerivative(v,3)/dya[0];
  }
  
  Osize_d[0]=Osizex;  Osize_d[1]=Osizey;
    
  /* Reserve room for 14 function variables(arrays)   */
  for (i=0; i<Nthreads; i++)
  {
    /*  Make Thread ID  */
    ThreadID1= (double *)malloc( 1* sizeof(double) );
    ThreadID1[0]=i;
    ThreadID[i]=ThreadID1;  

    /*  Make Thread Structure  */
    ThreadArgs1 = (double **)malloc( 13* sizeof( double * ) );  
    ThreadArgs1[0]=Bu;
    ThreadArgs1[1]=Bv;
    ThreadArgs1[2]=Isize_d;
    ThreadArgs1[3]=Osize_d;
    ThreadArgs1[4]=Iout;
    ThreadArgs1[5]=dxa;
    ThreadArgs1[6]=dya;
    ThreadArgs1[7]=ThreadID[i];
    ThreadArgs1[8]=Ox;
    ThreadArgs1[9]=Oy;
    ThreadArgs1[10]=Nthreadsd;
    ThreadArgs1[11]=Bdu;
    ThreadArgs1[12]=Bdv;

    ThreadArgs[i]=ThreadArgs1;
  
  StartThread(ThreadList[i], &transformvolume_jacobiandet, ThreadArgs[i])

  }
  
for (i=0; i<Nthreads; i++) { WaitForThreadFinish(ThreadList[i]); }

























  for (i=0; i<Nthreads; i++) 
  { 
    free(ThreadArgs[i]);
    free(ThreadID[i]);
  }

  free(ThreadArgs);
  free(ThreadID );
  free(ThreadList);
  
  
  free(Bu);
  free(Bdu);
  free(Bv);
  free(Bdv);
  
}
Example #4
0
// Main function ===============================================================
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
  double *a, *b, *Z, *X, *Y, a0;
  float  *Xf, *Yf;
  mwSize na, nb, order, nParam, MX, NX, Xndims, Zdims[MAX_NDIMS];
  bool   allocate_ba = false, allocate_Z = false, forward = true, hasZInput;
  char   Rev[2];
  const mwSize *Xdims;
  
  // Check number of inputs and outputs:
  if (nrhs < 3 || nrhs > 5) {
     mexErrMsgIdAndTxt(ERR_ID   "BadNInput",
                       ERR_HEAD "3 to 5 inputs required.");
  }
  if (nlhs > 2) {
     mexErrMsgIdAndTxt(ERR_ID   "BadNOutput",
                       ERR_HEAD "2 outputs allowed.");
  }
  
  // Check type of inputs:
  if (!mxIsDouble(b_in) || !mxIsDouble(a_in)) {
     mexErrMsgIdAndTxt(ERR_ID   "BadTypeInput1_2",
                       ERR_HEAD "Filter parameters must be DOUBLES.");
  }
  
  // Get dimensions of inputs:
  nb = mxGetNumberOfElements(b_in);
  na = mxGetNumberOfElements(a_in);
  MX = mxGetM(X_in);    // First dimension
  NX = mxGetN(X_in);    // Product of trailing dimensions
  
  // Reply empty array if the parameters or the signal is empty:
  if (na * nb * MX * NX == 0) {
     plhs[0] = mxCreateDoubleMatrix(0, 0, mxREAL);
     if (nrhs == 2) {
        plhs[1] = mxCreateDoubleMatrix(0, 0, mxREAL);
     }
     return;
  }
  
  // Get a and b as vectors of the same length:
  if (na == nb) {       // Use input vectors directly, if possible:
     b      = mxGetPr(b_in);
     a      = mxGetPr(a_in);
     nParam = nb;
     
     allocate_ba = (bool) (a[0] != 1.0);  // Normalization is needed
     
  } else {              // na differs from nb:
     nParam      = na > nb ? na : nb;
     allocate_ba = true;
  }
  order = nParam - 1;
  
  if (allocate_ba) {    // Create local copy of expanded [b] and [a]:
     // It is slightly cheaper to allocate one array only:
     if ((b = mxCalloc(2 * nParam, sizeof(double))) == NULL) {
        mexErrMsgIdAndTxt(ERR_ID   "NoMemory",
                          ERR_HEAD "Cannot get memory for parameters.");
     }
     a = b + nParam;    // Use 2nd half of vector [b] as [a]
     memcpy(b, mxGetPr(b_in), nb * sizeof(double));
     memcpy(a, mxGetPr(a_in), na * sizeof(double));
     
     // Normalize if 1st element of [a] does not equal 1.0:
     if (a[0] != 1.0) {
        NormalizeBA(b, nParam);
     }
  }
  
  // Create array for final conditions, insert value of initial conditions:
  Xndims = mxGetNumberOfDimensions(X_in);
  Xdims  = mxGetDimensions(X_in);
  if (Xndims > MAX_NDIMS) {
     mexErrMsgIdAndTxt(ERR_ID   "BadSizeSignal",
                       ERR_HEAD "Signal cannot have more than %d dimensions.",
                       MAX_NDIMS);
  }
  
  // Z has dimensions [order, DIMS(X, 2:end)]:
  memcpy(Zdims, Xdims, Xndims * sizeof(mwSize));
  Zdims[0] = order;
  
  // 4th input is existing and not empty:
  hasZInput = false;
  if (nrhs >= 4) {
     hasZInput = (bool) (!mxIsEmpty(Z_in));
  }
  
  if (hasZInput) { // Initial conditions provided as input:
     // Check dimensions of Z:
     if (mxGetM(Z_in) != order || mxGetN(Z_in) != NX) {
        mexErrMsgIdAndTxt(ERR_ID "BadSizeZ",
                   ERR_HEAD
                   "Dimensions of initial conditions do not match the signal.");
     }
     
     if (nlhs == 2) {  // Final conditions wanted:
        Z_out = mxCreateNumericArray(Xndims, Zdims, mxDOUBLE_CLASS, mxREAL);
        Z     = mxGetPr(Z_out);
     } else {          // Final conditions not caught in the caller:
        allocate_Z = true;
        if ((Z = mxCalloc(order * NX, sizeof(double))) == NULL) {
           mexErrMsgIdAndTxt(ERR_ID   "NoMemory",
                             ERR_HEAD "No memory for initial conditions.");
        }
     }
     
     // Copy value from input with a conversion to DOUBLE on demand:
     if (mxIsDouble(Z_in)) {
        memcpy(Z, mxGetPr(Z_in), order * NX * sizeof(double));
     } else if (mxIsSingle(Z_in)) {
        CopySingleToDouble(Z, (float *) mxGetData(Z_in), order * NX);
     } else {
        mexErrMsgIdAndTxt(ERR_ID "BadTypeInput4",
               ERR_HEAD "Initial conditions must be a DOUBLE or SINGLE array.");
     }
     
  } else {             // Initial conditions not provided:
     if (nlhs == 2) {  // Final conditions wanted:
        Z_out = mxCreateNumericArray(Xndims, Zdims, mxDOUBLE_CLASS, mxREAL);
        Z     = mxGetPr(Z_out);
     } else {          // Cheaper to to use malloc than creating a Matlab array:
        allocate_Z = true;
        if ((Z = mxCalloc(order * NX, sizeof(double))) == NULL) {
           mexErrMsgIdAndTxt(ERR_ID   "NoMemory",
                             ERR_HEAD "No memory for initial conditions.");
        }
     }
  }

  // Flag for forward processing: ----------------------------------------------
  // 'Reverse', 1, TRUE: Process signal in reverse order:
  if (nrhs == 5) {
     if (!mxIsEmpty(Rev_in)) {
        if (mxIsChar(Rev_in)) {
           mxGetString(Rev_in, Rev, 2);
           forward = (bool) ((*Rev != 'r') && (*Rev != 'R'));
        } else if (mxIsLogical(Rev_in)) {
           forward = (bool) (mxGetScalar(Rev_in) == 0);
        }
     } else {
        // Most likely the user tries to define the dimension as in FILTER:
        mexErrMsgIdAndTxt(ERR_ID   "BadTypeInput5",
                          ERR_HEAD "Reverse flag must be a string or LOGICAL.");
     }
  }
       
  // Call the calulator: -------------------------------------------------------
  if (mxIsDouble(X_in)) {
     // Create the output array:
     Y_out = mxCreateNumericArray(Xndims, Xdims, mxDOUBLE_CLASS, mxREAL);
     Y     = mxGetPr(Y_out);
     X     = mxGetPr(X_in);
     
     if (forward) {
#    if defined(__BORLAND__)
        // BCC 5.5 runs the unrolled loops with the half speed!
        CoreDoubleN(X, MX, NX, a, b, order, Z, Y);
#    else
        // Unrolled loops for common filter lengths:
        switch (order) {
           case 1:   CoreDouble2(X, MX, NX, a, b, Z, Y);  break;
           case 2:   CoreDouble3(X, MX, NX, a, b, Z, Y);  break;
           case 3:   CoreDouble4(X, MX, NX, a, b, Z, Y);  break;
           case 4:   CoreDouble5(X, MX, NX, a, b, Z, Y);  break;
           case 5:   CoreDouble6(X, MX, NX, a, b, Z, Y);  break;
           case 6:   CoreDouble7(X, MX, NX, a, b, Z, Y);  break;
           default:  CoreDoubleN(X, MX, NX, a, b, order, Z, Y);
        }
#    endif
     } else {  // Reverse order:
        CoreDoubleNR(X, MX, NX, a, b, order, Z, Y);
     }
     
  } else if (mxIsSingle(X_in)) {
     // Create the output array:
     Y_out = mxCreateNumericArray(Xndims, Xdims, mxSINGLE_CLASS, mxREAL);
     Yf    = (float *) mxGetData(Y_out);
     Xf    = (float *) mxGetData(X_in);
     
     if (forward) {
#    if defined(__BORLAND__)
        // BCC 5.5 runs the unrolled loops with the half speed!
        CoreSingleN(X, MX, NX, a, b, order, Z, Y);
#    else
        // Unrolled loops for common filter lengths:
        switch (order) {
           case 1:   CoreSingle2(Xf, MX, NX, a, b, Z, Yf);  break;
           case 2:   CoreSingle3(Xf, MX, NX, a, b, Z, Yf);  break;
           case 3:   CoreSingle4(Xf, MX, NX, a, b, Z, Yf);  break;
           case 4:   CoreSingle5(Xf, MX, NX, a, b, Z, Yf);  break;
           case 5:   CoreSingle6(Xf, MX, NX, a, b, Z, Yf);  break;
           case 6:   CoreSingle7(Xf, MX, NX, a, b, Z, Yf);  break;
           default:  CoreSingleN(Xf, MX, NX, a, b, order, Z, Yf);
        }
#    endif
     } else {  // Reverse order:
        CoreSingleNR(Xf, MX, NX, a, b, order, Z, Yf);
     }
     
  } else {  // Signal is neither a DOUBLE nor a SINGLE:
     mexErrMsgIdAndTxt(ERR_ID   "BadTypeInput3",
                       ERR_HEAD "Signal must be a DOUBLE or SINGLE array.");
  }
  
  // Cleanup:
  if (allocate_Z) {
     mxFree(Z);
  }
  if (allocate_ba) {
     mxFree(b);       // Frees [a] implicitely!
  }
  
  return;
}
Example #5
0
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
	if (!(nlhs==1))
	{
    	mexErrMsgIdAndTxt("MyToolbox:arrayProduct:nlhs","One output required.");
    }
    if (!(nrhs==2 || nrhs==3))
    {
    	mexErrMsgIdAndTxt("MyToolbox:arrayProduct:nrhs","Two double matrix and one optional structure are required.");
    }

	int i = 1;
	float tau     = PAR_DEFAULT_TAU;
	float lambda  = PAR_DEFAULT_LAMBDA;
	float theta   = PAR_DEFAULT_THETA;
	int   nscales = PAR_DEFAULT_NSCALES;
	float zfactor = PAR_DEFAULT_ZFACTOR;
	int   nwarps  = PAR_DEFAULT_NWARPS;
	float epsilon = PAR_DEFAULT_EPSILON;
	int   verbose = PAR_DEFAULT_VERBOSE;
	if (nrhs==3)
    {
      int tmp=0;
      double* ptr;
      for( tmp=0; tmp<mxGetNumberOfFields(prhs[2]);tmp++)
      {
        if ( strcmp(mxGetFieldNameByNumber(prhs[2],tmp),"tau")==0)
        {
          if (!(mxIsDouble(mxGetField(prhs[2],0,mxGetFieldNameByNumber(prhs[2],0)))))
          {
              mexErrMsgTxt("A double argument was expected.");
          }
          if (mxGetNumberOfElements((mxGetField(prhs[2],0,mxGetFieldNameByNumber(prhs[2],0))))!=1)
          {
            mexErrMsgTxt("Only one value was expected.");
          }
          ptr=mxGetPr(mxGetField(prhs[2],0,mxGetFieldNameByNumber(prhs[2],tmp)));
          if (ptr[0]> 0 && ptr[0]< 0.25)
          {
            tau=ptr[0];
          }
          else
          {
              mexErrMsgTxt("The tau value is not acceptable. For more information, type \"help tvl1\"");
          }
        }
          if ( strcmp(mxGetFieldNameByNumber(prhs[2],tmp),"lambda")==0)
          {
              if (!(mxIsDouble(mxGetField(prhs[2],0,mxGetFieldNameByNumber(prhs[2],0)))))
              {
                  mexErrMsgTxt("A double argument was expected.");
              }
              if (mxGetNumberOfElements((mxGetField(prhs[2],0,mxGetFieldNameByNumber(prhs[2],0))))!=1)
              {
                  mexErrMsgTxt("Only one value was expected.");
              }
              ptr=mxGetPr(mxGetField(prhs[2],0,mxGetFieldNameByNumber(prhs[2],tmp)));
              if (ptr[0]>0)
              {
                  lambda=ptr[0];
              }
              else
              {
                  mexErrMsgTxt("The lambda value is not acceptable. For more information, type \"help tvl1\"");
              }
          }
          if ( strcmp(mxGetFieldNameByNumber(prhs[2],tmp),"theta")==0)
          {
              if (!(mxIsDouble(mxGetField(prhs[2],0,mxGetFieldNameByNumber(prhs[2],0)))))
              {
                  mexErrMsgTxt("A double argument was expected.");
              }
              if (mxGetNumberOfElements((mxGetField(prhs[2],0,mxGetFieldNameByNumber(prhs[2],0))))!=1)
              {
                  mexErrMsgTxt("Only one value was expected.");
              }
              ptr=mxGetPr(mxGetField(prhs[2],0,mxGetFieldNameByNumber(prhs[2],tmp)));
              if (ptr[0]>0)
              {
                  theta=ptr[0];
              }
              else
              {
                  mexErrMsgTxt("The theta value is not acceptable. For more information, type \"help tvl1\"");
              }
          }
          if ( strcmp(mxGetFieldNameByNumber(prhs[2],tmp),"nscales")==0)
          {
              if (!(mxIsDouble(mxGetField(prhs[2],0,mxGetFieldNameByNumber(prhs[2],0)))))
              {
                  mexErrMsgTxt("A double argument was expected.");
              }
              if (mxGetNumberOfElements((mxGetField(prhs[2],0,mxGetFieldNameByNumber(prhs[2],0))))!=1)
              {
                  mexErrMsgTxt("Only one value was expected.");
              }
              ptr=mxGetPr(mxGetField(prhs[2],0,mxGetFieldNameByNumber(prhs[2],tmp)));
              if (ptr[0]>0)
              {
                  nscales=ptr[0];
              }
              else
              {
                  mexErrMsgTxt("The nscales value is not acceptable. For more information, type \"help tvl1\"");
              }
          }
          
          if ( strcmp(mxGetFieldNameByNumber(prhs[2],tmp),"zfactor")==0)
          {
              if (!(mxIsDouble(mxGetField(prhs[2],0,mxGetFieldNameByNumber(prhs[2],0)))))
              {
                  mexErrMsgTxt("A double argument was expected.");
              }
              if (mxGetNumberOfElements((mxGetField(prhs[2],0,mxGetFieldNameByNumber(prhs[2],0))))!=1)
              {
                  mexErrMsgTxt("Only one value was expected.");
              }
              ptr=mxGetPr(mxGetField(prhs[2],0,mxGetFieldNameByNumber(prhs[2],tmp)));
              if (ptr[0]>0)
              {
                  zfactor=ptr[0];
              }
              else
              {
                  mexErrMsgTxt("The zfactor value is not acceptable. For more information, type \"help tvl1\"");
              }
          }
          
          if ( strcmp(mxGetFieldNameByNumber(prhs[2],tmp),"nwarps")==0)
          {
              if (!(mxIsDouble(mxGetField(prhs[2],0,mxGetFieldNameByNumber(prhs[2],0)))))
              {
                  mexErrMsgTxt("A double argument was expected.");
              }
              if (mxGetNumberOfElements((mxGetField(prhs[2],0,mxGetFieldNameByNumber(prhs[2],0))))!=1)
              {
                  mexErrMsgTxt("Only one value was expected.");
              }
              ptr=mxGetPr(mxGetField(prhs[2],0,mxGetFieldNameByNumber(prhs[2],tmp)));
              if (ptr[0]>0)
              {
                  nwarps=ptr[0];
              }
              else
              {
                  mexErrMsgTxt("The nwarps value is not acceptable. For more information, type \"help tvl1\"");
              }
          }
          
          if ( strcmp(mxGetFieldNameByNumber(prhs[2],tmp),"epsilon")==0)
          {
              if (!(mxIsDouble(mxGetField(prhs[2],0,mxGetFieldNameByNumber(prhs[2],0)))))
              {
                  mexErrMsgTxt("A double argument was expected.");
              }
              if (mxGetNumberOfElements((mxGetField(prhs[2],0,mxGetFieldNameByNumber(prhs[2],0))))!=1)
              {
                  mexErrMsgTxt("Only one value was expected.");
              }
              ptr=mxGetPr(mxGetField(prhs[2],0,mxGetFieldNameByNumber(prhs[2],tmp)));
              if (ptr[0]>0)
              {
                  epsilon=ptr[0];
              }
              else
              {
                  mexErrMsgTxt("The epsilon value is not acceptable. For more information, type \"help tvl1\"");
              }
          }
          
      }
	}

	if (tau <= 0 || tau > 0.25) {
		tau = PAR_DEFAULT_TAU;
		if (verbose) mexPrintf("warning: "
				"tau changed to %g\n", tau);
	}
	if (lambda <= 0) {
		lambda = PAR_DEFAULT_LAMBDA;
		if (verbose) mexPrintf("warning: "
				"lambda changed to %g\n", lambda);
	}
	if (theta <= 0) {
		theta = PAR_DEFAULT_THETA;
		if (verbose) mexPrintf("warning: "
				"theta changed to %g\n", theta);
	}
	if (nscales <= 0) {
		nscales = PAR_DEFAULT_NSCALES;
		if (verbose) mexPrintf("warning: "
				"nscales changed to %d\n", nscales);
	}
	if (zfactor <= 0 || zfactor >= 1) {
		zfactor = PAR_DEFAULT_ZFACTOR;
		if (verbose) mexPrintf( "warning: "
				"zfactor changed to %g\n", zfactor);
	}
	if (nwarps <= 0) {
		nwarps = PAR_DEFAULT_NWARPS;
		if (verbose) mexPrintf( "warning: "
				"nwarps changed to %d\n", nwarps);
	}
	if (epsilon <= 0) {
		epsilon = PAR_DEFAULT_EPSILON;
		if (verbose) mexPrintf("warning: "
				"epsilon changed to %f\n", epsilon);
	}
    
	int    nx = mxGetN(prhs[0]);
	int    ny = mxGetM(prhs[0]);
	int    nx2 = mxGetN(prhs[1]);
	int    ny2 = mxGetM(prhs[1]);
	float *I0=malloc(nx*ny*sizeof(float));
	int tmpx, tmpy;
   for (tmpx=0; tmpx<nx; tmpx++) 
      for (tmpy=0; tmpy<ny; tmpy++) 
		   I0[tmpx+tmpy*nx] = (float)(mxGetPr(prhs[0]))[tmpy+tmpx*ny];

	float *I1=malloc(nx2*ny2*sizeof(float));
   for (tmpx=0; tmpx<nx2; tmpx++) 
      for (tmpy=0; tmpy<ny2; tmpy++) 
		   I1[tmpx+tmpy*nx] = (float)(mxGetPr(prhs[1]))[tmpy+tmpx*ny];

		if (nx == nx2 && ny == ny2)
	{

		const float N = 1 + log(hypot(nx, ny)/16.0) / log(1/zfactor);
		if (N < nscales)
			nscales = N;
		if (verbose)
		{
			mexPrintf(
				"tau=%f lambda=%f theta=%f nscales=%d "
				"zfactor=%f nwarps=%d epsilon=%g\n",
				tau, lambda, theta, nscales,
				zfactor, nwarps, epsilon);
		}

		float *u = xmalloc(2 * nx * ny * sizeof(*u));
		float *v = u + nx*ny;

		Dual_TVL1_optic_flow_multiscale(
				I0, I1, u, v, nx, ny, tau, lambda, theta,
				nscales, zfactor, nwarps, epsilon, verbose
		);
		mwSize dim = 3;
    	const mwSize dims[3]={ny,nx,2};
    	plhs[0]=mxCreateNumericArray(dim, dims,mxDOUBLE_CLASS,mxREAL);
    	double* pointeur=(double*)mxGetPr(plhs[0]);
      for (tmpy=0; tmpy<ny; tmpy++) 
         for (tmpx=0; tmpx<nx; tmpx++) 
         {
        	   pointeur[tmpy+tmpx*ny + 0    ]=(double)u[tmpx+tmpy*nx];
        	   pointeur[tmpy+tmpx*ny + nx*ny]=(double)v[tmpx+tmpy*nx];
         }
		free(I0);
		free(I1);
		free(u);
	} 
	else
	{
		mexErrMsgTxt("ERROR: input images size mismatch ");
	}
}
Example #6
0
mxArray * toMx(GPUtype *r, int isscalar=0) {
	// garbage collector
	//MyGCObj<GPUtype> mgc;
	//mgc.setPtr(r);

	mxArray *plhs[1];
	mwSize dims[2] = {1,1};

	if ((r->getNumel() == 1)||(isscalar==1)) {
		if (r->isComplex()) {
			if (r->getType()==gpuCFLOAT) {
				Complex tmpr;
				try {

					GPUopCudaMemcpy(&tmpr, r->getGPUptr(), GPU_SIZE_OF_CFLOAT * 1,
							cudaMemcpyDeviceToHost, r->getGPUmanager());

				} catch (GPUexception ex) {
					mexErrMsgTxt(ex.getError());
				}
				//plhs[0] = mxCreateDoubleMatrix(1, 1, mxCOMPLEX);
				plhs[0] = mxCreateNumericArray(2, dims, mxSINGLE_CLASS, mxCOMPLEX);
				memcpy (mxGetPr(plhs[0]), &tmpr.x, sizeof(float) );
				memcpy (mxGetPi(plhs[0]), &tmpr.y, sizeof(float) );
				//*mxGetPr(plhs[0]) = tmpr.x;
				//*mxGetPi(plhs[0]) = tmpr.y;
			} else if (r->getType()==gpuCDOUBLE){
				DoubleComplex tmpr;
				try {

					GPUopCudaMemcpy(&tmpr, r->getGPUptr(), GPU_SIZE_OF_CDOUBLE * 1,
							cudaMemcpyDeviceToHost, r->getGPUmanager());

				} catch (GPUexception ex) {
					mexErrMsgTxt(ex.getError());
				}
				//plhs[0] = mxCreateDoubleMatrix(1, 1, mxCOMPLEX);
				plhs[0] = mxCreateNumericArray(2, dims, mxDOUBLE_CLASS, mxCOMPLEX);
				memcpy (mxGetPr(plhs[0]), &tmpr.x, sizeof(double) );
				memcpy (mxGetPi(plhs[0]), &tmpr.y, sizeof(double) );

				//*mxGetPr(plhs[0]) = tmpr.x;
				//*mxGetPi(plhs[0]) = tmpr.y;
			}
		} else {
			if (r->getType()==gpuFLOAT) {
				float tmpr = 0.0;
				try {

					GPUopCudaMemcpy(&tmpr, r->getGPUptr(), GPU_SIZE_OF_FLOAT * 1,
							cudaMemcpyDeviceToHost, r->getGPUmanager());

				} catch (GPUexception ex) {
					mexErrMsgTxt(ex.getError());
				}
				//plhs[0] = mxCreateDoubleScalar(tmpr);
				plhs[0] = mxCreateNumericArray(2, dims, mxSINGLE_CLASS, mxREAL);
				memcpy (mxGetPr(plhs[0]), &tmpr, sizeof(float) );
				//*mxGetPr(plhs[0]) = tmpr;
			} else if (r->getType()==gpuDOUBLE) {
				double tmpr = 0.0;
				try {

					GPUopCudaMemcpy(&tmpr, r->getGPUptr(), GPU_SIZE_OF_DOUBLE * 1,
							cudaMemcpyDeviceToHost, r->getGPUmanager());

				} catch (GPUexception ex) {
					mexErrMsgTxt(ex.getError());
				}
				//plhs[0] = mxCreateDoubleScalar(tmpr);
				plhs[0] = mxCreateNumericArray(2, dims, mxDOUBLE_CLASS, mxREAL);
				memcpy (mxGetPr(plhs[0]), &tmpr, sizeof(double) );
				//*mxGetPr(plhs[0]) = tmpr;
			}
		}

		// remove first from Garbage collector
		//mgc.remPtr(r);

		// must delete r
		delete r;
	} else {
	  GPUmanager *gman = r->getGPUmanager();
	  int slot = 0;
	  // request a free slot in cache
		gpuTYPE_t mxtype = gpuNOTDEF;
		
		// first I search for a cached element. mxtype is the tyep of cached
		// element I am looking for. 
		// If the cached element is not found, I have to create a new GPUsingle/GPUdouble
		// which is not registered to the cache. 

		if (r->isFloat())
			mxtype = gpuFLOAT; // complex as well
		if (r->isDouble())
			mxtype = gpuDOUBLE; // complex as well

		// NPN yet implemented
	  //void *mxtmp = gman->extCacheGetFreeSlot(&slot, mxtype);
	  void *mxtmp = gman->extCacheGetFreeSlot(&slot, gpuNOTDEF);

	  if (slot<0) {
	    // internal error
	    mexErrMsgTxt(ERROR_MXID_CACHEINTERNAL);
	  }

	  if (mxtmp==NULL) {
	    // the mxArray is not in cache
      mxArray *prhs[2];
      prhs[0] = mxCreateDoubleScalar(slot);
      prhs[1] = prhs[0];

      //mxArray *tmpr = toMxStruct(r);

      if (r->getType()==gpuCFLOAT) {
        mexCallMATLAB(1, plhs, 2, prhs, "GPUsingle");
      } else if (r->getType()==gpuFLOAT){
        mexCallMATLAB(1, plhs, 2, prhs, "GPUsingle");
      } else if (r->getType()==gpuCDOUBLE){
        mexCallMATLAB(1, plhs, 2, prhs, "GPUdouble");
      } else if (r->getType()==gpuDOUBLE){
        mexCallMATLAB(1, plhs, 2, prhs, "GPUdouble");
      }

      gman->extCacheRegisterPtrBySlot(slot, mxID(plhs[0]), plhs[0], r, gpuNOTDEF);

      //mexPrintf("%p -> %p\n", plhs[0], r);

      // clean up
      mxDestroyArray(prhs[0]);

	  } else {
	    // shoud no be here, not impl.
	    mexErrMsgTxt(ERROR_MXID_CACHEINTERNAL);
	    plhs[0] = (mxArray *) mxtmp;
	    gman->extCacheRegisterPtrBySlot(slot, mxID(plhs[0]), NULL, r, mxtype);
	  }
	  //mexPrintf("************** begin return mx ****************\n");
	  //gman->extCachePrint();

	}

	// remove from gc
	//mgc.remPtr(r);
	mxArray * tmp = plhs[0];
	//printMx1(tmp, 0);
	//mexPrintf("************** end return mx ****************\n");
	//mexPrintf("<- %p\n",tmp->reserved2);
  //mexPrintf("<- %p\n",tmp->data.number_array.pdata);

  return plhs[0];

}
Example #7
0
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
  double *vecA, *vecB, *pA,*pB;
  double *dist;
  unsigned int i, ptsA, ptsB, dim, kptsA, kptsB;
  int *sym;
  
  if (nrhs == 0)
  {
    mexPrintf("Usage: d = chi2_mex(X,Y);\n");
    mexPrintf("where X and Y are matrices of dimension [dim,npts]\n");
    mexPrintf("\nExample\n a = rand(2,10);\n b = rand(2,20);\n d = chi2_mex(a,b);\n");
    return;
  }

  if (nrhs != 3) {
    mexPrintf("three input arguments expected: A, B, and sym, sym says wether A and B are the same");
    return;
  }

  if (mxGetNumberOfDimensions(prhs[0]) != 2 || mxGetNumberOfDimensions(prhs[1]) != 2) {
    mexPrintf("inputs must be two dimensional");
    return;
  }
  
  mxClassID the_class = mxGetClassID(prhs[0]);
    
  if(the_class != mxDOUBLE_CLASS) {
    mexErrMsgTxt("Histograms should have double precision!\n");
  }
            

  vecA = (double *)mxGetPr(prhs[0]);
  vecB = (double *)mxGetPr(prhs[1]);
  sym = (int *)mxGetPr(prhs[2]);
  
  ptsA = mxGetN(prhs[0]);
  ptsB = mxGetN(prhs[1]);
  dim = mxGetM(prhs[0]);
  
  if (dim != mxGetM(prhs[1]))
  {
    mexPrintf("Dimension mismatch");
    return;
  }
  
  const mwSize ndims[2] = {ptsA, ptsB};
  
  mxArray* mxdist = mxCreateNumericArray(2, ndims,the_class,mxREAL);    
  dist = (double *)mxGetData(mxdist);
  /*plhs[0] = mxCreateDoubleMatrix(ptsA,ptsB,mxREAL);*/
  /*dist = (float *)mxGetPr(plhs[0]);*/
    
  /*chi2_distance_float(dim,ptsB,vecB,ptsA,vecA,dist);    */
          
  /* printf("get_num_threads: %d\n", omp_get_num_threads()); 
     printf("hello");*/
 
  if(*sym) {
    chi2sym_distance_double(dim, ptsB, vecB, dist); 
  } else {
    chi2_distance_double(dim, ptsB, vecB, ptsA, vecA, dist); 
  }
  
  plhs[0] = mxdist;
  
  return;
}
/* Gateway of LEMIRE_ND_MINENGINE */
void mexFunction(int nlhs, mxArray *plhs[],
        int nrhs, const mxArray *prhs[]) {
    
    mxClassID ClassID;
    
    /* pointer to the index array */
    double *idx, *minidx;
    /* Data pointers, which one are used depends on the class of A */
    double *adouble, *valdouble;
    float *asingle, *valsingle;
    int64 *aint64, *valint64;
    int32 *aint32, *valint32;
    int16 *aint16, *valint16;
    int08 *aint08, *valint08;
    uint64 *auint64, *valuint64;
    uint32 *auint32, *valuint32;
    uint16 *auint16, *valuint16;
    uint08 *auint08, *valuint08;

    mwSize i, pleft, n, window;
    mwSize imax, margin, linidx;
    int left, lstart, size;
    mwSize *Wedge; /* wedge */
    int nWedge; /* wedge number of elements (0 is empty wedge) */
    int Wedgefirst, Wedgelast; /* Indices of two ends of the wedge */
    int shape;
    
    mwSize p, q, j, k;
    mwIndex stepA, stepMinMax;
    const mwSize* dimA;
    mwSize dimOut[3];
    
    void *adata, *valdata;
    double *idxdata, *minidxdata;
    
    /* Check number of arguments */
    if (nrhs!=4)
        mexErrMsgTxt("LEMIRE_ND_MINENGINE: four arguments are required.");
    
     /* Get the shape */
    shape = (int)mxGetScalar(SHAPE);
    
    /* Get class of input matrix A */
    ClassID = mxGetClassID(A);
    
    if (mxGetClassID(IDX) != mxDOUBLE_CLASS)
        mexErrMsgTxt("LEMIRE_ND_MINENGINE: idx must be double.");
    
    /* Do not support on sparse */
    if (mxIsSparse(A))
        mexErrMsgTxt("LEMIRE_ND_MINENGINE: First input A must be full.");       
    
    /* Get the number of elements of A */
    /* Get the size, MUST BE two or three, no check */
    dimA = mxGetDimensions(A);
    p = dimA[0];
    n = dimA[1];
    if (mxGetNumberOfDimensions(A)<3)
        q = 1; /* third dimension is singleton */
    else
        q = dimA[2];
   
    /* Window input must be double */
    if (mxGetClassID(WINDOW)!=mxDOUBLE_CLASS)
        mexErrMsgTxt("LEMIRE_ND_MINENGINE: Second input WINDOW must be double.");
    
    /* Get the window size, cast it in mwSize */
    window = (mwSize)(*mxGetPr(WINDOW));
    margin = window-1;
    
    if (window<1) /* Check if it's valid */
        mexErrMsgTxt("LEMIRE_ND_MINENGINE: windows must be 1 or greater.");   
    if (window>n || window>MAXINT)
        mexErrMsgTxt("LEMIRE_ND_MINENGINE: windows larger than data length.");
    
    /* Allocate wedges buffers for L and U, each is size (window+1) */
    size = (int)(window+1);
    Wedge = mxMalloc(size*sizeof(mwSize));
    if (Wedge==NULL) mexErrMsgTxt("LEMIRE_ND_MINENGINE: out of memory.");
    
    /* This parameters configure for three cases:
     * - full scan (minimum 1-element intersecting with window), or
     * - same scan (output has the same size as input)
     * - valid scan (full overlapping with window) */ 
    if (shape==FULL_SHAPE) {
        dimOut[1] = n+margin;
        lstart = -(int)(margin);
    } else if (shape==SAME_SHAPE) {
        dimOut[1] = n;
        lstart = -(int)(margin/2);
    } else { /* if (shape==VALID_SHAPE) */
        dimOut[1] = n-margin;
        lstart = 0;
    }
    
    /* The last index to be scanned */
    imax = (dimOut[1] + margin) + lstart;
    
    /* Create output arrays */
    dimOut[0] = p;
    dimOut[2] = q;

    MINVAL = mxCreateNumericArray(3, dimOut, ClassID, mxREAL);
    MINIDX = mxCreateNumericArray(3, dimOut, mxDOUBLE_CLASS, mxREAL); 
    /* Check if allocation is succeeded */
    if ((MINVAL==NULL) || (MINIDX==NULL))
         mexErrMsgTxt("LEMIRE_ND_MINENGINE: out of memory.");    
      
    /* Jump step of the third dimension */
    stepA = p*n; /* for A */
    stepMinMax = p*dimOut[1]; /* step for output */
    
    /* Get data pointers */
    adata = mxGetData(A);
    idxdata = mxGetPr(IDX); 
    valdata = mxGetData(MINVAL);
    minidxdata = mxGetPr(MINIDX);
        
    /* Call the engine depending on ClassID */
    switch (ClassID) {
        case mxDOUBLE_CLASS:
            SCAN(adouble, valdouble, double);
            break;
        case mxSINGLE_CLASS:
            SCAN(asingle, valsingle, float);
            break;
        case mxINT64_CLASS:
            SCAN(aint64, valint64, int64);
            break;
        case mxUINT64_CLASS:
            SCAN(auint64, valuint64, uint64);
            break;
        case mxINT32_CLASS:
            SCAN(aint32, valint32, int32);
            break;
        case mxUINT32_CLASS:
            SCAN(auint32, valuint32, uint32);
            break;
        case mxCHAR_CLASS:
            SCAN(auint16, valuint16, uint16);
            break;
        case mxINT16_CLASS:
            SCAN(aint16, valint16, int16);
            break;
        case mxUINT16_CLASS:
            SCAN(auint16, valuint16, uint16);
            break;
        case mxLOGICAL_CLASS:
            SCAN(auint08, valuint08, uint08);
            break;
        case mxINT8_CLASS:
            SCAN(aint08, valint08, int08);
            break;
        case mxUINT8_CLASS:
            SCAN(auint08, valuint08, uint08);
            break;
        default:
            mexErrMsgTxt("LEMIRE_ND_MINENGINE: Class not supported.");
    } /* switch */
    
    /* Free the buffer */
    mxFree(Wedge);
    
    return;
    
} /* Gateway LEMIRE_ND_MINENGINE */
Example #9
0
/* ---------------------------------------------------------------------- */
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
	int     i, ix, nRows, nCols, nBands, ngot, sz = 1, dims[3];
	size_t  nPts;
	double *pd;
	mxClassID classid = mxUINT8_CLASS;
	FILE *f = NULL;
	mxArray *rslt = NULL;

	if (nrhs < 1) {
		mexPrintf("popenr  Y = popenr(X[,N[,F]])  Open and read an external process\n");
		mexPrintf("        When X is a string, that string is executed as a new process\n");
		mexPrintf("        and Y is returned as a handle (integer) to that stream.\n");
		mexPrintf("        Subsequent calls to popenr(Y,N) with that handle return the next N\n");
		mexPrintf("        values read from the standard ouptut of converted to Matlab values\n");
		mexPrintf("        according to the format string F (default: char).\n");
		mexPrintf("        If N is a row vector with [nRows nCols nBands] and type 'char' then data is\n");
		mexPrintf("        internaly transposed to Matlab orientation and output is a [MxNxnBands] array.\n");
		mexPrintf("        A call with N set to -1 means to close the stream.\n");
		return;
	}
	/* look at the data */
	/* Check to be sure input argument is a string. */
	if ((mxIsChar(prhs[0]))) {
		/* first argument is string - opening a new command */
		char *cmd;
		int tabix = findfreetab();
		
		if (tabix < 0) mexErrMsgTxt("Out of file table slots.");

		cmd = mxArrayToString(prhs[0]);
		f = popen(cmd, "r");
		mxFree(cmd);
		if (f == NULL) mexErrMsgTxt("Error running external command.");

		/* else have a new command path - save the handle */
		filetab[tabix] = f;
		/* return the index */
		if (nlhs > 0) {
			mxArray *rslt = mxCreateDoubleMatrix(1,1, mxREAL);
			plhs[0] = rslt;
			pd = mxGetPr(rslt);
			*pd = (double)tabix;
		}
		return;
	}

	if (nrhs < 2) mexErrMsgTxt("apparently accessing handle, but no N argument");
	
	/* get the handle */
	if (mxGetN(prhs[0]) == 0) mexErrMsgTxt("handle argument is empty");

	ix = (int)*mxGetPr(prhs[0]);
	if (ix < filetabix) f = filetab[ix];
	if (f == NULL) mexErrMsgTxt("invalid handle");

	/* how many items required? */
	if (mxGetN(prhs[1]) == 0) mexErrMsgTxt("length argument is empty");

	nBands = 1;
	pd = mxGetPr(prhs[1]);
	if (mxGetN(prhs[1]) == 1) {
		nRows = (int)pd[0];		nCols = 1;
	}
	else if (mxGetN(prhs[1]) == 2){
		nRows = (int)pd[0];		nCols = (int)pd[1];
	}
	else if (mxGetN(prhs[1]) == 3){
		nRows = (int)pd[0];		nCols = (int)pd[1];		nBands = (int)pd[2];
	}
	else
		mexErrMsgTxt("More than 3 dimensional data is not supported");
	
	/* maybe close */
	if (nRows < 0) {
		pclose(f);
		filetab[ix] = NULL;
		return;
	}

	/* what is the format? */
	if (nrhs > 2) {
		char *fmtstr = NULL;

		if (!mxIsChar(prhs[2])) mexErrMsgTxt("format arg must be a string");

		fmtstr = mxArrayToString(prhs[2]);
		if (!strcmp(fmtstr, "uint8") || !strcmp(fmtstr, "char")) {
			classid = mxUINT8_CLASS;	sz = 1;
		}
		else if (!strcmp(fmtstr, "int8")) {
			classid = mxINT8_CLASS;		sz = 1;
		}
		else if (!strcmp(fmtstr, "int16")) {
			classid = mxINT16_CLASS;	sz = 2;
		}
		else if (!strcmp(fmtstr, "uint16")) {
			classid = mxUINT16_CLASS;	sz = 2;
		}
		else if (!strcmp(fmtstr, "int32")) {
			classid = mxINT32_CLASS;	sz = 4;
		}
		else if (!strcmp(fmtstr, "uint32")) {
			classid = mxUINT32_CLASS;	sz = 4;
		}
		else if (!strcmp(fmtstr, "float") || !strcmp(fmtstr, "single")) {
			classid = mxSINGLE_CLASS;	sz = 4;
		}
		else if (!strcmp(fmtstr, "double")) {
			classid = mxDOUBLE_CLASS;	sz = 8;
		}
		else
			mexErrMsgTxt("unrecognized format");
	}

	/* do the read */
	dims[0] = nRows;		dims[1] = nCols;		dims[2] = nBands;
	rslt = mxCreateNumericArray((nBands == 1 ? 2 : 3), dims, classid, mxREAL);
	nPts = (size_t)nRows * nCols * nBands;
	if (nCols == 1)
		ngot = fread(mxGetData(rslt), sz, nPts, f);
	else {
		int k, row, col, band;
		size_t nXY = (size_t)nRows * nCols;
		void *pv = mxGetData(rslt);
		if (classid == mxUINT8_CLASS) {
			unsigned char *tmp = mxMalloc(nCols * nBands * sz);
			unsigned char *p = (unsigned char *)pv;
			for (row = 0; row < nRows; row++) {
				fread(tmp, sz, nCols * nBands, f);		/* Read a row of nCols by nBands bytes of data */
				for (col = 0; col < nCols; col++) {
					for (band = 0; band < nBands; band++) {
						p[row + col*nRows + band*nXY] = tmp[band + col*nBands];
					}
				}
			}
			mxFree(tmp);
		}
	}


	if (ngot < nPts) {
		void *pv = mxGetData(rslt);
		mxRealloc(pv, ngot * sz);
	}

	plhs[0] = rslt;
}
Example #10
0
void mexFunction(int nlhs, mxArray *plhs[],
                 int nrhs, const mxArray *prhs[])
{

  /* [R, [n]] = general_radon_c( theta, rho, M, dx, dy [, interpolation, method, constraint, valid, rho_x] ) */

  /* INPUTS: */
  /* theta: vector of angles */
  /* rho: vector of (local) rho values */
  /* M: data matrix */
  /* dx,dy: sample size in x (row) and y (column) dimension */
  /* interpolation: interpolation method (0=nearest or 1=linear) */
  /* method: 0=integral, 1=sum, 2=mean, 3=slice, 4=product, 5=logsum */
  /* constraint: 0=no constraint, 1=loop over rows only (i.e. only one element per row contributes to a line), 2=loop over columns only */
  /* valid: 0/1 (valid lines are those lines that span the whole width or height of the input matrix) */
  /* rho_x: 0/1 (if 1, indicates that rho is specified as the intercept with the horizontal center line,
     rather than the distance from the origin, this could be useful if you want rho to be in the same units as the x dimension.
     Notice however, that in this mode, rho will go to infinity if theta approaches +/- pi ) */

  /* OUTPUTS: */
  /* if method is one of integral, sum, mean, product
  /* R: radon transform matrix if method is one of integral, sum, mean, product */
  /* n: number of elements in original matrix contributing to each line*/ 
  /* if method is slice */
  /* R: cell array of projections along lines specified by theta and rho pairs */
  /* n: number of elements in original matrix contributing to each line*/ 

  /* variables */
  int T,R,M,N;
  int t,r,m,n;
  double *theta, *rho, *g;
  double delta_x, delta_y;
  mxArray *out, *tmp, *out2;
  double *pout;
  short *pout2;
  double alpha, beta, betap, costheta, sintheta, rhooffset;
  int mmin, mmax, nmin, nmax, amax;
  double xmin, ymin;
  int rstart, rend;
  double sum;
  int count, method, lininterp, valid, rho_x, constraint;
  double eps=1e-9;
  int indx;
  double nfloat, w;
  int dims[3];
  const char *mclass;
  mxArray *mcopy;

  /* check optional input parameters */
  if (nrhs>5 && mxGetScalar(prhs[5]) ) {
    lininterp=1;
  } else {
    lininterp=0; /* default interpolation is nearest */
  }
  if (nrhs>6 ) {
    method=mxGetScalar(prhs[6]);
  } else {
    method=0; /* default method is integral */
  }
  if (nrhs>7) {
    constraint = (int) mxGetScalar(prhs[7]);
    if (constraint!=1 && constraint!=2)
      constraint = 0;
  } else {
    constraint = 0; /* by default no constraint */
  }
  if (nrhs>8 && mxGetScalar(prhs[8]) ) {
    valid = 1;
  } else {
    valid = 0; /* by default compute all lines */
  }
  if (nrhs>9 && mxGetScalar(prhs[9]) ) {
    rho_x = 1;
  } else {
    rho_x = 0; /* by default rho specifies distance from origin */
  }


  mclass = mxGetClassName(prhs[2]);
  if (!mxIsDouble(prhs[2])) {
    if ( mexCallMATLAB(1, &mcopy, 1, (mxArray**)&prhs[2], "double") )
      mexErrMsgTxt("Could not convert matrix to double precision");
    
    g = mxGetPr( mcopy );
  } else {
    g = mxGetPr( prhs[2] );
  }

  /* get input arguments */
  T = mxGetNumberOfElements( prhs[0] ); /* length theta vector */
  R = mxGetNumberOfElements( prhs[1] ); /* length rho vector */
  M = mxGetM( prhs[2] ); /* number of rows matrix M */
  N = mxGetN( prhs[2] ); /* number of columns matrix M */

  theta = mxGetPr( prhs[0] ); /* pointer to theta vector */
  rho = mxGetPr( prhs[1] ); /* pointer to rho vector */

  delta_x = mxGetScalar( prhs[3] ); /* sample size in x (row) dimension */
  delta_y = mxGetScalar( prhs[4] ); /* sample size in y (column) dimension */

  xmin = -delta_x*(M-1)/2; /* x of lower left corner of matrix M (local coordinates) */
  ymin = -delta_y*(N-1)/2; /* y of lower left corner of matrix M (local coordinates) */


  /* create output matrices */
  if (method==3) {
    out = mxCreateCellMatrix(T,1);
  } else {
    out = mxCreateDoubleMatrix( T,R,mxREAL);
    pout = mxGetPr( out );
  }

  if (nlhs>1) {
    if (method==3) {
      out2 = mxCreateNumericMatrix(T,2,mxINT16_CLASS,mxREAL);
    } else {
      dims[0]=T;
      dims[1]=R;
      dims[2]=2;      
      out2 = mxCreateNumericArray(3,(const int*) &dims, mxINT16_CLASS,mxREAL);
    }
    pout2 = (short*) mxGetPr( out2 );
  }

  /* (minimal) error checking */
  if (method==3 && T!=R)
    mexErrMsgTxt("Theta and rho vectors have incompatible lengths");


  for (t=0;t<T;t++) { /* loop through all angles */

    costheta = cos( theta[t] );
    sintheta = sin( theta[t] );
      
    /* decide whether to loop over samples in x or y dimension */
    if (constraint==1 || (constraint==0 && ( fabs(sintheta)>(delta_x/sqrt(delta_x*delta_x+delta_y*delta_y)) ) ) ) { /* loop over rows */
	
      rhooffset = xmin*costheta + ymin*sintheta;
      alpha = -(delta_x/delta_y)*(costheta/sintheta); /* alpha parameter of line */
	
      /* initialize rho start and end */
      if (method==3) {
	rstart = t;
	rend = rstart+1;
      } else {
	rstart = 0;
	rend = R;
      }
	
      /* loop over all rho values */
      for (r=rstart;r<rend;r++ ) {
	  
	/* compute beta parameter of line */
	if (rho_x)
	  beta = (rho[r]*costheta-rhooffset)/(delta_y*sintheta);
	else
	  beta = (rho[r]-rhooffset)/(delta_y*sintheta);
	  
	/* compute rows to loop over */
	if (lininterp) { 
	  if (alpha>eps) {
	    mmin=(int)ceil(-(beta-eps)/alpha);
	    mmax=1+(int)floor((N-beta-1-eps)/alpha);
	  } else if (alpha<-eps) {
	    mmin=(int)ceil((N-beta-1-eps)/alpha);
	    mmax=1+(int)floor(-(beta-eps)/alpha);
	  } else if (((beta-eps)>0) && ((beta+eps)<(N-1))) {
	    mmin=0;
	    mmax=M;
	  } else {
	    mmin=0;
	    mmax=-1;
	  }
	} else {
	  betap=beta+0.5;
	  if (alpha>eps) {
	    mmin=(int)ceil(-(betap-eps)/alpha);
	    mmax=1+(int)floor((N-betap-eps)/alpha);
	  } else if (alpha<-eps) {
	    mmin=(int)ceil((N-betap-eps)/alpha);
	    mmax=1+(int)floor(-(betap-eps)/alpha);
	  } else if (((betap-eps)>0) && ((betap+eps)<N)) {
	    mmin=0;
	    mmax=M;
	  } else {
	    mmin=0;
	    mmax=-1;
	  }
	}
	if (mmin<0) mmin=0;
	if (mmax>M) mmax=M;
	count=MAX(0,mmax-mmin); /* number of rows to loop over */
	  
	/* check if line is valid */
	if ( ( (valid) && count<M && fabs(alpha*count)<(N-2) ) || (count<=0) ) {
	  if (method==3) {
	    if (nlhs>1) {
	      pout2[t] = 0;
	      pout2[t+T] = 0;
	    }
	  } else {
	    pout[ t+T*r] = mxGetNaN();
	    if (nlhs>1) {
	      pout2[ t+T*r ] = 0;
	      pout2[ t+T*r+T*R ] = 0;
	    }
	  }
	  continue;
	}
	  
	if (method==3) { /* process slice method */
	    
	  tmp = mxCreateDoubleMatrix(count, 1, mxREAL);
	  mxSetCell(out, t, tmp );
	    
/* 	  if (alpha<-eps) */
/* 	    pout = mxGetPr(tmp) + count - 1; */
/* 	  else */
	  pout = mxGetPr(tmp);
	    
	  if (lininterp) {

	    for (m=mmin; m<mmax; m++) {
		
	      nfloat = alpha*m+beta;
	      n = floor(nfloat);
	      w = nfloat-n;
		
	      if (fabs(w)<eps) {
		(*pout)=(g[m+M*n]);
	      } else {
		(*pout)=(g[m+M*n]*(1-w)+g[m+M*(n+1)]*w);
	      }
		
/* 	      if (alpha<-eps) */
/* 		pout--; */
/* 	      else */
	      pout++;
	      
	    }
	  } else {
	    for (m=mmin; m<mmax; m++) {
	      indx = round(alpha*m+beta); /* nearest neighbour */
	      (*pout)= g[m+M*indx];
/* 	      if (alpha<-eps) */
/* 		pout--; */
/* 	      else */
	      pout++;
	    }
	  }
	    
	} else if (method==4) { /* process product method */
	    
	  /* initialize sum to one */
	  sum=1;

	  if (lininterp) {	    

	    for (m=mmin; m<mmax; m++) {
		
	      nfloat = alpha*m+beta;
	      n = floor(nfloat);
	      w = nfloat-n;
		
	      if (fabs(w)<eps) {
		sum*=g[m+M*n];
	      } else {
		sum*=g[m+M*n]*(1-w)+g[m+M*(n+1)]*w;
	      }
		
	    } 

	  } else {

	    for (m=mmin; m<mmax; m++) {

	      indx = round(alpha*m+beta); /* nearest neighbour */
	      sum *= g[m+M*indx];

	    }

	  }
	    
	  pout[t+T*r] = sum;

	} else if (method==5) { /* process log sum method */
	    
	  /* initialize sum to one */
	  sum=0;

	  if (lininterp) {	    

	    for (m=mmin; m<mmax; m++) {
		
	      nfloat = alpha*m+beta;
	      n = floor(nfloat);
	      w = nfloat-n;
		
	      if (fabs(w)<eps) {
		sum+=log(g[m+M*n]);
	      } else {
		sum+=log(g[m+M*n]*(1-w)+g[m+M*(n+1)]*w);
	      }
		
	    } 

	  } else {

	    for (m=mmin; m<mmax; m++) {

	      indx = round(alpha*m+beta); /* nearest neighbour */
	      sum += log(g[m+M*indx]);

	    }

	  }
	    
	  pout[t+T*r] = sum;
	    
	} else { /* process integral, sum and mean methods */
	    
	  /* initialize sum to zero */
	  sum = 0;

	  if (lininterp) {
	    
	    for (m=mmin; m<mmax; m++) {
		
	      nfloat = alpha*m+beta;
	      n = floor(nfloat);
	      w = nfloat-n;
		
	      if (fabs(w)<eps) {
		sum+=g[m+M*n];
	      } else {
		sum+=g[m+M*n]*(1-w)+g[m+M*(n+1)]*w;
	      }
	      
	    }

	  } else {

	    for (m=mmin; m<mmax; m++) {

	      indx = round(alpha*m+beta); /* nearest neighbour */
	      sum += g[m+M*indx];

	    }

	  }
	    
	  if (method==0) /* integral */
	    pout[ t+T*r ] = delta_x*sum/fabs(sintheta);
	  else if (method==1) /* sum */
	    pout[ t+T*r ] = sum;
	  else if (method==2) /* mean */
	    pout[ t+T*r ] = sum/count;
	    
	} /* end conditional on method */
	  
	if (nlhs>1) {
	    
	  if (method==3) {
	    pout2[t] = mmin+1;
	    pout2[t+T] = mmax;
	  } else {
	    pout2[t+T*r] = mmin+1;
	    pout2[t+T*r+T*R] = mmax;
	  }
	    
	}	  
	  
      } /* end loop over rho values */	
	
    } else { /* loop over columns */
	
      alpha = -(delta_y/delta_x)*(sintheta/costheta);
      rhooffset = xmin*costheta + ymin*sintheta;
	
      /* initialize rho start and end */
      if (method==3) {
	rstart = t;
	rend = rstart+1;
      } else {
	rstart = 0;
	rend = R;
      }
	
      /* loop over all rho values */
      for ( r=rstart;r<rend;r++ ) {
	  
	if (rho_x)
	  beta = (rho[r]*costheta-rhooffset)/(delta_x*costheta);
	else
	  beta = (rho[r]-rhooffset)/(delta_x*costheta);
	  
	/* compute columns to loop over */
	if (lininterp) {
	  if (alpha>eps) {
	    nmin=(int)ceil(-(beta-eps)/alpha);
	    nmax=1+(int)floor((M-beta-1-eps)/alpha);
	  } else if (alpha<-eps) {
	    nmin=(int)ceil((M-beta-1-eps)/alpha);
	    nmax=1+(int)floor(-(beta-eps)/alpha);
	  } else if (((beta-eps)>0) && ((beta+eps)<(M-1))) {
	    nmin=0;
	    nmax=N;
	  } else {
	    nmin=0;
	    nmax=-1;
	  }
	} else {
	  betap=beta+0.5;
	  if (alpha>eps) {
	    nmin=(int)ceil(-(betap-eps)/alpha);
	    nmax=1+(int)floor((M-betap-eps)/alpha);
	  } else if (alpha<-eps) {
	    nmin=(int)ceil((M-betap-eps)/alpha);
	    nmax=1+(int)floor(-(betap-eps)/alpha);
	  } else if (((betap-eps)>0) && ((betap+eps)<M)) {
	    nmin=0;
	    nmax=N;
	  } else {
	    nmin=0;
	    nmax=-1;
	  }
	}
	if (nmin<0) nmin=0;
	if (nmax>N) nmax=N;
	count=MAX(0,nmax-nmin); /* number of columns to loop over */
	  
	/* check if line is valid */
	if ( ( (valid) && count<N && fabs(alpha*count)<(M-2) ) || (count<=0) ) {
	  if (method==3) {
	    if (nlhs>1) {
	      pout2[t] = 0;
	      pout2[t+T] = 0;
	    }
	  } else {
	    pout[ t+T*r] = mxGetNaN();
	    if (nlhs>1) {
	      pout2[ t+T*r ] = 0;
	      pout2[ t+T*r+T*R ] = 0;
	    }
	  }	    
	  continue;
	}
	  
	if (method==3) { /* process slice method */
	    
	  tmp = mxCreateDoubleMatrix(count, 1, mxREAL);
	  mxSetCell(out, t, tmp );
	    
	  pout = mxGetPr(tmp);

	  if (lininterp) {
	    
	    for (n=nmin;n<nmax;n++) {
		
	      nfloat = alpha*n+beta;
	      m = floor(nfloat);
	      w = nfloat-m;
		
	      if (fabs(w)<eps) {
		(*pout)=(g[m+M*n]);
	      } else {
		(*pout)=(g[m+M*n]*(1-w)+g[m+1+M*n]*w);
	      }

	      pout++;
		
	    }

	  } else {

	    for (n=nmin;n<nmax;n++) {
		
	      indx = round(alpha*n+beta); /* nearest neighbour */
	      *(pout)=g[n*M+indx];
	      pout++;
		
	    }
	      
	  }
	    
	} else if (method==4) { /* process product */
	    
	  /* initialize sum to one */
	  sum=1;

	  if (lininterp) {
	    
	    for (n=nmin; n<nmax; n++) {
		
	      nfloat = alpha*n+beta;
	      m = floor(nfloat);
	      w = nfloat-m;
		
	      if (fabs(w)<eps) {
		sum*=g[m+M*n];
	      } else {
		sum*=g[m+M*n]*(1-w)+g[m+M*(n+1)]*w;
	      }
		
	    } 

	  } else {

	    for (n=nmin; n<nmax; n++) {
	      indx = round(alpha*n+beta); /* nearest neighbour */
	      sum *= g[n*M+indx];
	    }

	  }
	    
	  pout[t+T*r] = sum;

	} else if (method==5) { /* process log sum */
	    
	  /* initialize sum to one */
	  sum=0;

	  if (lininterp) {
	    
	    for (n=nmin; n<nmax; n++) {
		
	      nfloat = alpha*n+beta;
	      m = floor(nfloat);
	      w = nfloat-m;
		
	      if (fabs(w)<eps) {
		sum+=log(g[m+M*n]);
	      } else {
		sum+=log(g[m+M*n]*(1-w)+g[m+M*(n+1)]*w);
	      }
		
	    } 

	  } else {

	    for (n=nmin; n<nmax; n++) {
	      indx = round(alpha*n+beta); /* nearest neighbour */
	      sum += log(g[n*M+indx]);
	    }

	  }
	    
	  pout[t+T*r] = sum;
	    
	} else { /* process integral, sum and mean methods */
	    
	  /* initialize sum to zero */
	  sum = 0;

	  if (lininterp) {
	    
	    for (n=nmin;n<nmax;n++) {
		
	      nfloat = alpha*n+beta;
	      m = floor(nfloat);
	      w = nfloat-m;
		
	      if (fabs(w)<eps) {
		sum+=g[m+M*n];
	      } else {
		sum+=g[m+M*n]*(1-w)+g[m+1+M*n]*w;
	      }
		
	    }

	  } else {
	      
	    for (n=nmin;n<nmax;n++) {
	      indx = round(alpha*n+beta); /* nearest neighbour */
	      sum+=g[n*M+indx];
	    }	      

	  }
	      
	  if (method==0) /* integral */
	    pout[ t+T*r ] = delta_y*sum/fabs(costheta);
	  else if (method==1) /* sum */
	    pout[ t+T*r ] = sum;
	  else if (method==2) /* mean */
	    pout[ t+T*r ] = sum/count;
	    
	} /* end conditional on method */

	if (nlhs>1) {
	    
	  if (method==3) {
	    pout2[t] = nmin+1;
	    pout2[t+T] = nmax;
	  } else {
	    pout2[t+T*r] = nmin+1;
	    pout2[t+T*r+T*R] = nmax;
	  }
	    
	}
	  
      } /* end loop over rho values */
	
    } /* end conditional rows/columns */

  } /* end loop over angles */

  /* set output arguments */
  plhs[0] = out;
  
  if (nlhs>1)
    plhs[1] = out2;


} /* end mexFunction */
Example #11
0
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
	mxClassID cid;
	const int *dim;
	const unsigned char *uc;
	const unsigned short *us;
	const unsigned int *ul;
	const double *dbl;
	bool forward = 1;
	int nd, ne, c = 0, cm, si;
	int odim[2] = {1, 2};
	double *odbl;

	if (nrhs < 1 || nrhs > 2 || nlhs > 2)
		mexErrMsgTxt("Bad number of input/output arguments.");
	cid = mxGetClassID(*prhs);
	dim = mxGetDimensions(*prhs);
	nd = mxGetNumberOfDimensions(*prhs);
	ne = mxGetNumberOfElements(*prhs);
	si = 0;
	if ((nrhs > 1) &&
	    mxIsDouble(prhs[1]) &&
	    (mxGetNumberOfElements(prhs[1]) == 1)) {
		si = (int) *((double*) mxGetPr(prhs[1]));
		if (si > 0) {
			--si;
			if (si >= ne)
				mexErrMsgTxt(ff_errbadindex);
		} else if (si < 0) {
			forward = 0;
			si = ne + si;
			if (si < 0)
				mexErrMsgTxt(ff_errbadindex);
		} else
			mexErrMsgTxt(ff_errbadindex);
	}

	switch (cid) {
		case mxLOGICAL_CLASS:
		case mxINT8_CLASS:
		case mxUINT8_CLASS:
			uc = (const unsigned char*) mxGetData(*prhs);
			uc = &uc[si];
			if (forward) {
				for (c = si; c < ne; ++c)
					if (*uc++ != 0)
						break;
			} else {
				for (c = si; c >= 0; --c)
					if (*uc-- != 0)
						break;
			}
			break;

		case mxINT16_CLASS:
		case mxUINT16_CLASS:
			us = (const unsigned short*) mxGetData(*prhs);
			us = &us[si];
			if (forward) {
				for (c = si; c < ne; ++c)
					if (*us++ != 0)
						break;
			} else {
				for (c = si; c >= 0; --c)
					if (*us-- != 0)
						break;
			}
			break;

		case mxINT32_CLASS:
		case mxUINT32_CLASS:
		case mxSINGLE_CLASS:
			ul = (const unsigned int*) mxGetData(*prhs);
			ul = &ul[si];
			if (forward) {
				for (c = si; c < ne; ++c)
					if (*ul++ != 0)
						break;
			} else {
				for (c = si; c >= 0; --c)
					if (*ul-- != 0)
						break;
			}
			break;

		case mxDOUBLE_CLASS:
			dbl = (const double*) mxGetData(*prhs);
			dbl = &dbl[si];
			if (forward) {
				for (c = si; c < ne; ++c)
					if (*dbl++ != 0.0)
						break;
			} else {
				for (c = si; c >= 0; --c)
					if (*dbl-- != 0.0)
						break;
			}
			break;

		default: mexErrMsgTxt("Invalid input class.");
			 break;
	}

	if (c < 0 || c >= ne) {

		*plhs = mxCreateNumericArray(2, ff_emptyarray, mxDOUBLE_CLASS, mxREAL);
		if (nlhs > 1)
			plhs[1] = mxCreateNumericArray(2, ff_emptyarray, mxDOUBLE_CLASS, mxREAL);

	} else {

		*plhs = mxCreateNumericArray(2, ff_scalararray, mxDOUBLE_CLASS, mxREAL);
		if (*plhs == NULL)
			mexErrMsgTxt("Error allocating 1x1 output argument.");
		odbl = (double *) mxGetData(*plhs);
		if (odbl == NULL)
			mexErrMsgTxt("Error addressing 1x1 output argument.");
		*odbl = (double) (c + 1);

		if (nlhs > 1) {
			odim[1] = nd;
			plhs[1] = mxCreateNumericArray(2, odim, mxDOUBLE_CLASS, mxREAL);
			if (plhs[1] == NULL)
				mexErrMsgTxt("Error allocating 1xN output argument.");
			odbl = (double *) mxGetData(plhs[1]);
			if (odbl == NULL)
				mexErrMsgTxt("Error addressing 1xN output argument.");
			for ( ; nd > 0; --nd) {
				cm = c % *dim;
				*odbl++ = (double) (cm + 1);
				c = (int) (((double) c) / ((double) *dim++));
			}
		}
	}
}
Example #12
0
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
   /* Variables */
   int n, s,s1,s2,n1,n2,e, yInd,
   nNodes, nEdges, maxState, sizeEdgeBel[3], sizeLogZ[2],
   *y,
   *edgeEnds, *nStates;
   
   double pot,Z,
   *nodePot, *edgePot, *nodeBel, *edgeBel, *logZ;
   
   /* Input */
   
   nodePot = mxGetPr(prhs[0]);
   edgePot = mxGetPr(prhs[1]);
   edgeEnds = mxGetPr(prhs[2]);
   nStates = mxGetPr(prhs[3]);
   
   /* Compute Sizes */
   
   nNodes = mxGetDimensions(prhs[0])[0];
   maxState = mxGetDimensions(prhs[0])[1];
   nEdges = mxGetDimensions(prhs[2])[0];
   decrementEdgeEnds(edgeEnds,nEdges);
   
   /* Output */
   sizeEdgeBel[0] = maxState;
   sizeEdgeBel[1] = maxState;
   sizeEdgeBel[2] = nEdges;
   sizeLogZ[0] = 1;
   sizeLogZ[1] = 1;
   plhs[0] = mxCreateNumericArray(2,mxGetDimensions(prhs[0]),mxDOUBLE_CLASS,mxREAL);
   plhs[1] = mxCreateNumericArray(3,sizeEdgeBel,mxDOUBLE_CLASS,mxREAL);
   plhs[2] = mxCreateNumericArray(2,sizeLogZ,mxDOUBLE_CLASS,mxREAL);
   nodeBel = mxGetPr(plhs[0]);
   edgeBel = mxGetPr(plhs[1]);
   logZ = mxGetPr(plhs[2]);
   
   /* Initialize */
   y = mxCalloc(nNodes,sizeof(int));
   Z = 0;
   
   while(1)
   {
      pot = 1;
      
   /* Node */
      for(n = 0; n < nNodes; n++)
      {
         pot *= nodePot[n + nNodes*y[n]];
      }
      
   /* Edges */
      for(e = 0; e < nEdges; e++)
      {
         n1 = edgeEnds[e];
         n2 = edgeEnds[e+nEdges];
         pot *= edgePot[y[n1] + maxState*(y[n2] + maxState*e)];
      }
      
   /* Update nodeBel */
      for(n = 0; n < nNodes; n++)
      {
         nodeBel[n + nNodes*y[n]] += pot;
      }
      
   /* Update edgeBel */
      for (e = 0; e < nEdges; e++)
      {
         n1 = edgeEnds[e];
         n2 = edgeEnds[e+nEdges];
         edgeBel[y[n1] + maxState*(y[n2] + maxState*e)] += pot;
      }
      
   /* Update Z */
      Z += pot;
      
   /* Go to next y */
      
      for(yInd = 0; yInd < nNodes; yInd++)
      {
         y[yInd] += 1;
         if(y[yInd] < nStates[yInd])
         {
          break;  
         }
         else
         {
            y[yInd] = 0;
         }
      }

   /* Stop when we are done all y combinations */
      if(yInd == nNodes)
      {
         break;
      }
   }
   
   /* Normalize by Z */
   for(n = 0; n < nNodes; n++)
   {
      for(s = 0; s < nStates[n];s++)
      {
         nodeBel[n + nNodes*s] /= Z;
      }
   }
   for(e = 0; e < nEdges; e++)
   {
      n1 = edgeEnds[e];
      n2 = edgeEnds[e+nEdges];
      for(s1 = 0; s1 < nStates[n1]; s1++)
      {
         for(s2 = 0; s2 < nStates[n2]; s2++)
         {
            edgeBel[s1 + maxState*(s2 + maxState*e)] /= Z;
         }
      }
   }
   *logZ = log(Z);
   
   /* Free memory */
   mxFree(y);
}
Example #13
0
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
	int dim, m, n, l, ntot, dims[3];
 	float *data1, *data2, *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("VAL = BsplCo2GdYZero(COEFF, [nx ny (nz)], [offx "
			"offy (offz)], [mx my (mz)], {wx wy (wz)}, deg);\n");
                mexPrintf("[in]\n");
                mexPrintf("\tCOEFF              : 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("\t{wx wy (wz)}       : deformed value vectors\n");
                mexPrintf("\tdeg                : (opt) spline basis degree "
			"{default: 3}\n");
                mexPrintf("[out]\n");
                mexPrintf("\tVAL                : interpolated grad y "
			"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 */
	plhs[0] = mxCreateNumericArray(mxGetNumberOfElements(prhs[1]), dims, 
			mxSINGLE_CLASS, mxREAL);

	/* Retrieve the output data */
    	data2 = mxGetData(plhs[0]);

	if (ntot == 0)
	{
		if (dim == 3)
		{
			BatchInterpolatedGradY3DZero(data2, data1, m, n, l, nx, 
				offx, mx, ny, offy, my, nz, offz, mz, 
				(long)spline); 
		}
		else
		{
			BatchInterpolatedGradY2DZero(data2, data1, m, n, nx, 
				offx, mx, ny, offy, my, (long)spline); 
		}
	}
	else
	{
		if (dim == 3)
		{
			BatchInterpolatedGradY3DZeroWarp(data2, data1, m, n, l,
 				nx, offx, mx, wx, ny, offy, my, wy, nz, offz, 
				mz, wz, (long)spline); 
		}
		else
		{
			BatchInterpolatedGradY2DZeroWarp(data2, data1, m, n, nx,
 				offx, mx, wx, ny, offy, my, wy, (long)spline); 
		}
	}
}
Example #14
0
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]){
	int     i, j, count, NB, NS, siz_b, siz_s, ndim, temp, maximize;
	int     *mask, *sx, *sy, *cpsy, *subs, *s, *cpsy2, *ssize;
	double  *pb, *ps, *bp, *sp, *pbd;


	siz_b = mxGetNumberOfElements(prhs[1]);
	siz_s = mxGetNumberOfElements(prhs[3]);
	pb = mxGetPr(prhs[1]);
	ps = mxGetPr(prhs[3]);

	NB = mxGetNumberOfElements(prhs[0]);
	bp = mxGetPr(prhs[0]);

	pbd = mxGetPr(prhs[2]);

	if(nrhs < 5) maximize = 0;
	else maximize = (int)mxGetScalar(prhs[4]);

	if(siz_s == 0){
		plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);
		sp = mxGetPr(plhs[0]);
		if(maximize){
			for(i=0; i<NB; i++){
				*sp = (*sp < bp[i])? bp[i] : *sp;
			}
		}
		else{
			for(i=0; i<NB; i++){
				*sp += bp[i];
			}
		}
		return;
	}

	mask = malloc(siz_s * sizeof(int));
	ssize = malloc(siz_s * sizeof(int));
	count = 0;
	for(i=0; i<siz_s; i++){
		for(j=0; j<siz_b; j++){
			if(ps[i] == pb[j]){
				mask[count] = j;
				count++;
				break;
			}
		}
	}
	
	ndim = siz_b;
	sx = (int *)malloc(sizeof(int)*ndim);
	sy = (int *)malloc(sizeof(int)*ndim);
	for(i=0; i<ndim; i++){
		sx[i] = (int)pbd[i];
		sy[i] = 1;
	}
	for(i=0; i<siz_s; i++){
		temp = mask[i];
		sy[temp] = sx[temp];
		ssize[i] = sx[temp];
	}

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

	plhs[0] = mxCreateNumericArray(siz_s, ssize, mxDOUBLE_CLASS, mxREAL);
	sp = mxGetPr(plhs[0]);

	if(NS == 1){
		if(maximize){
			for(i=0; i<NB; i++){
				*sp = (*sp < bp[i])? bp[i] : *sp;
			}
		}
		else{
			for(i=0; i<NB; i++){
				*sp += bp[i];
			}
		}
		free(mask);
		free(sx);
		free(sy);
		free(ssize);
		return;
	}

	if(NS == NB){
		for(i=0; i<NB; i++) *sp++ = *bp++;
		free(mask);
		free(sx);
		free(sy);
		free(ssize);
		return;
	}

	s = (int *)malloc(sizeof(int)*ndim);
	*(cpsy = (int *)malloc(sizeof(int)*ndim)) = 1;
	subs =   (int *)malloc(sizeof(int)*ndim);
	cpsy2 =  (int *)malloc(sizeof(int)*ndim);
	for(i = 0; i < ndim; i++){
		subs[i] = 0;
		s[i] = sx[i] - 1;
	}
			
	for(i = 0; i < ndim-1; i++){
		cpsy[i+1] = cpsy[i]*sy[i]--;
		cpsy2[i] = cpsy[i]*sy[i];
	}
	cpsy2[ndim-1] = cpsy[ndim-1]*(--sy[ndim-1]);

	if(maximize){
		for(j=0; j<NB; j++){
			*sp = (*sp < *bp)? *bp : *sp;
			bp++;
			for(i = 0; i < ndim; i++){
				if(subs[i] == s[i]){
					subs[i] = 0;
					if(sy[i])
						sp -= cpsy2[i];
				}
				else{
					subs[i]++;
					if(sy[i])
						sp += cpsy[i];
					break;
				}
			}
		}
	}
	else{
		for(j=0; j<NB; j++){
			*sp += *bp++;
			for(i = 0; i < ndim; i++){
				if(subs[i] == s[i]){
					subs[i] = 0;
					if(sy[i])
						sp -= cpsy2[i];
				}
				else{
					subs[i]++;
					if(sy[i])
						sp += cpsy[i];
					break;
				}
			}
		}
	}

	free(sx);
	free(sy);
	free(s);
	free(cpsy);
	free(subs);
	free(cpsy2);
    free(mask);
	free(ssize);
}
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
    int n,sizL[2],sizD[2],i,j,q,s,
    *P;
    
    double mu,gamma,xi,delta,beta,maxVal,theta,
    *c,    *H, *L, *D, *A;
    
    /* Input */
    H = mxGetPr(prhs[0]);
    if (nrhs == 1)
    {
        mu = 1e-12;
    }
    else
    {
        mu = mxGetScalar(prhs[1]);
    }
    
    /* Compute Sizes */
    n = mxGetDimensions(prhs[0])[0];
    
    /* Form Output */
    sizL[0] = n;
    sizL[1] = n;
    plhs[0] = mxCreateNumericArray(2,sizL,mxDOUBLE_CLASS,mxREAL);
    L = mxGetPr(plhs[0]);
    sizD[0] = n;
    sizD[1] = 1;
    plhs[1] = mxCreateNumericArray(2,sizD,mxDOUBLE_CLASS,mxREAL);
    D = mxGetPr(plhs[1]);
    plhs[2] = mxCreateNumericArray(2,sizD,mxINT32_CLASS,mxREAL);
    P = (int*)mxGetData(plhs[2]);
    
    /* Initialize */
    c = mxCalloc(n*n,sizeof(double));
    A = mxCalloc(n*n,sizeof(double));
    
    for (i = 0; i < n; i++)
    {
        P[i] = i;
        for (j = 0;j < n; j++)
        {
            A[i+n*j] = H[i+n*j];
        }
    }
    
    gamma = 0;
    for (i = 0; i < n; i++)
    {
        L[i+n*i] = 1;
        c[i+n*i] = A[i+n*i];
    }
    
    /* Compute modification parameters */
    gamma = -1;
    xi = -1;
    for (i = 0; i < n; i++)
    {
        gamma = mymax(gamma,absolute(A[i+n*i]));
        for (j = 0;j < n; j++)
        {
            //printf("A(%d,%d) = %f, %f\n",i,j,A[i+n*j],absolute(A[i+n*j]));
            if (i != j)
                xi = mymax(xi,absolute(A[i+n*j]));
        }
    }
    delta = mu*mymax(gamma+xi,1);
    
    if (n > 1)
    {
        beta = sqrt(mymax(gamma,mymax(mu,xi/sqrt(n*n-1))));
    }
    else
    {
        beta = sqrt(mymax(gamma,mu));
    }
    
    for (j = 0; j < n; j++)
    {
        
    /* Find q that results in Best Permutation with j */
        maxVal = -1;
        q = 0;
        for(i = j; i < n; i++)
        {
            if (absolute(c[i+n*i]) > maxVal)
            {
                maxVal = mymax(maxVal,absolute(c[i+n*i]));
                q = i;
            }
        }
        
        /* Permute D,c,L,A,P */
        permute(D,j,q);
        permuteInt(P,j,q);
        permuteRows(c,j,q,n);
        permuteCols(c,j,q,n);
        permuteRows(L,j,q,n);
        permuteCols(L,j,q,n);
        permuteRows(A,j,q,n);
        permuteCols(A,j,q,n);
        
        for(s = 0; s <= j-1; s++)
            L[j+n*s] = c[j+n*s]/D[s];
        
        for(i = j+1; i < n; i++)
        {
            c[i+j*n] = A[i+j*n];
            for(s = 0; s <= j-1; s++)
            {
                c[i+j*n] -= L[j+n*s]*c[i+n*s];
            }
        }
        
        theta = 0;
        if (j < n-1)
        {
            for(i = j+1;i < n; i++)
                theta = mymax(theta,absolute(c[i+n*j]));
        }
        
        D[j] = mymax(absolute(c[j+n*j]),mymax(delta,theta*theta/(beta*beta)));
        
        if (j < n-1)
        {
            for(i = j+1; i < n; i++)
            {
                c[i+n*i] = c[i+n*i] - c[i+n*j]*c[i+n*j]/D[j];
            }
        }
        
    }
    
    for(i = 0; i < n; i++)
        P[i]++;
    
    mxFree(c);
    mxFree(A);
}
Example #16
0
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
    const mxArray *a, *b;
    mxArray *c;
    const mwSize *dimsa, *dimsb;
    mwSize *dimsc;
    double *aa, *bb, *cc;
    int H, W, i, j, ii, jj, ni, ndima, ndimb, colors, color, Nfilters, nf, N, Hfilter, Wfilter, Hres, Wres;
    int strideH = 1, strideW = 1;

    a = prhs[0];
    b = prhs[1];
    
    dimsa = mxGetDimensions(a);
    dimsb = mxGetDimensions(b);
    
    ndima = mxGetNumberOfDimensions(a);
    ndimb = mxGetNumberOfDimensions(b);
    
    H = dimsa[0]; W = dimsa[1];
    
    if (ndima <= 2) Nfilters = 1;
    else Nfilters = dimsa[2];
    if (ndima <= 3) N = 1;
    else N = dimsa[3];
    
    Hfilter = dimsb[0];
    Wfilter = dimsb[1];
    if (ndimb <= 2) colors = 1;
    else colors = dimsb[2];

    if (nrhs > 2) {
        strideW = (int)*((double*)mxGetPr(prhs[2]));

        if (nrhs > 3)
            strideH = (int)*((double*)mxGetPr(prhs[3]));
        else
            strideH = strideW;
    }
    
    Wres = W*strideW + Wfilter - 1; Hres = H*strideH + Hfilter - 1;
    
    dimsc = (mwSize*)mxMalloc(sizeof(mwSize)*4);
    dimsc[0] = Hres; dimsc[1] = Wres; dimsc[2] = colors; dimsc[3] = N;
    c = plhs[0] = mxCreateNumericArray(4, dimsc, mxDOUBLE_CLASS, mxREAL);
    mxFree(dimsc);
    
    aa = mxGetPr(a);
    bb = mxGetPr(b);
    cc = mxGetPr(c);
    
    for (ni = 0; ni < N; ni++)
        for (color = 0; color < colors; color++)
            for (j = 0; j < W; j++)
                for (i = 0; i < H; i++) {
                    
                    for (nf = 0; nf < Nfilters; nf++)
                        for (jj = 0; jj < Wfilter; jj++)
                            for (ii = 0; ii < Hfilter; ii++)
                                cc[(i*strideH+ii) + Hres * (j*strideW+jj) + Wres * Hres * color + colors * Wres * Hres * ni] +=
                                    aa[i + H * j + W * H * nf + Nfilters * W * H * ni] *
                                    bb[ii + Hfilter * jj + Hfilter * Wfilter * color + colors * Hfilter * Wfilter * nf];
                }
}
Example #17
0
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
  int imgrows, imgcols, numsigmas, numangles, nwedges, maxradius;
  int i, j, k, anglewedges, plot = 0;
  enum imgtype type;
  double *sigmas, *spacing, *dimensions, *angles, *maxclusters, wedgeangle;
  double maxsigma = -1.0;
  mxArray **strength = NULL, **orientation = NULL, **uncertainty = NULL;
  mxArray **abnormality = NULL;
  void *imgdata;
  int dims[3];
  char buf[20] = "xxxxxxxxxxxxxxxxxxx\0";

  /* Before error checking, remove the optional string argument at the end */
  if (nrhs > 0 && mxIsChar(prhs[nrhs-1])) {
    if (mxGetString(prhs[nrhs-1], buf, 20) == 0 && buf[0] == 'p')
      plot = 1;
    nrhs--; /* Don't want to process it numerically later on */
  }

  /* Error checking (duh) */
  if (nrhs < 2 || nrhs > 7)
    mexErrMsgTxt("Incorrect number of arguments supplied");

  if (nlhs < 1 || nlhs > 4)
    mexErrMsgTxt("Between 1 and 4 output matrices should be supplied");

  if (mxGetNumberOfDimensions(prhs[0]) != 3)
    mexErrMsgTxt("Image should be M x N x 3");

  if (!mxIsUint8(prhs[0]) && !mxIsDouble(prhs[0]))
    mexErrMsgTxt("Image data should be uint8 or double");

  if (mxGetM(prhs[1]) != 1)
    mexErrMsgTxt("Sigmas must be a scalar or a row vector");

  if (mxGetN(prhs[1]) == 0)
    mexErrMsgTxt("Empty sigma vector is not allowed");

  if (nrhs >= 3 && mxGetM(prhs[2]) != 1)
    mexErrMsgTxt("Spacing must be a scalar or a row vector");

  if (nrhs >= 3 && mxGetN(prhs[2]) != 1 && mxGetN(prhs[2]) != mxGetN(prhs[1]))
    mexErrMsgTxt("Spacing must be a scalar or same length as scale vector");

  if (nrhs >= 4 && mxGetM(prhs[3]) != 1)
    mexErrMsgTxt("Image sub-dimensions must be a scalar or a row vector");

  if (nrhs >= 4 && (mxGetN(prhs[3]) == 3 || mxGetN(prhs[3]) > 4))
    mexErrMsgTxt("Image sub-dimension vector must have 1, 2, or 4 entries");

  if (nrhs >= 5 && mxGetM(prhs[4]) != 1)
    mexErrMsgTxt("Angles must be a scalar or a row vector");

  /* Collect meta-data about each argument */
  /* Argument #0: the image */
  imgrows = mxGetM(prhs[0]);
  imgcols = mxGetN(prhs[0]) / 3; /* mxGetN counts over dimensions 2-d */
  if (mxIsUint8(prhs[0]))
    type = RGBImg;
  else
    type = LabImg;
  imgdata = mxGetData(prhs[0]);

  /* Argument #1: one or more standard deviation values */
  /* Modified 31 July 1999 so that standard deviations (sigmas) rather than
   * radii are specified; also, sigmas can be floating-point values */
  numsigmas = mxGetN(prhs[1]);
  sigmas = mxGetPr(prhs[1]);
  for (i = 0; i < numsigmas; i++)
    if (sigmas[i] > maxsigma)
      maxsigma = sigmas[i];
  maxradius = ceil(3 * maxsigma);
  if (maxsigma * 2 > imgrows || maxsigma * 2 > imgcols)
    mexErrMsgTxt("Image is too small for maximum scale chosen");

  /* Argument #2: the spacing for each application of the operator */
  if (nrhs >= 3 && mxGetN(prhs[2]) > 1)
    spacing = mxGetPr(prhs[2]);
  else { 
    spacing = (double *)mxCalloc(numsigmas,sizeof(double));
    for (i = 0; i < numsigmas; i++)
      spacing[i] = (nrhs >= 3) ? mxGetScalar(prhs[2]) : 1;
  }

  /* Argument #3: Dimensions of the sub-image to find edges over */
  if (nrhs >= 4 && mxGetN(prhs[3]) == 4) {
    dimensions = mxGetPr(prhs[3]); /* Dimensions specified */
    if (dimensions[0] < maxradius) {
      mexWarnMsgTxt("Dimension entry 1 below minimum row");
      dimensions[0] = maxradius;
    }
    if (dimensions[1] < maxradius) {
      mexWarnMsgTxt("Dimension entry 2 below minimum column");
      dimensions[1] = maxradius;
    }
    if (dimensions[2] > imgrows - maxradius) {
      mexWarnMsgTxt("Dimension entry 3 above maximum row");
      dimensions[2] = imgrows - maxradius;
    }
    if (dimensions[3] > imgcols - maxradius) {
      mexWarnMsgTxt("Dimension entry 4 above maximum column");
      dimensions[3] = imgcols - maxradius;
    }
    if (dimensions[2] < dimensions[0] || dimensions[3] < dimensions[1])
      mexErrMsgTxt("Dimensions are [TR LC BR RC] with BR >= TR and RC >= LC");
  } else {
    dimensions = (double *)mxCalloc(4,sizeof(double));
    if (nrhs < 4 || mxGetN(prhs[3]) == 1) { /* Whole image */
      dimensions[0] = maxradius;
      dimensions[1] = maxradius;
      dimensions[2] = imgrows - maxradius;
      dimensions[3] = imgcols - maxradius;
    } else { /* One point */
      dimensions[0] = mxGetPr(prhs[3])[0];
      dimensions[1] = mxGetPr(prhs[3])[1];
      dimensions[2] = mxGetPr(prhs[3])[0];
      dimensions[3] = mxGetPr(prhs[3])[1];
      if (dimensions[0] < maxradius || dimensions[1] < maxradius ||
	  dimensions[2] > imgrows - maxradius || 
          dimensions[3] > imgcols - maxradius)
	mexErrMsgTxt("Point is inoperable by maximum scale");
    }
  }

  /* Argument #4: Number of angles (alpha values in ICCV99) to compute */
  if (nrhs >= 5 && mxGetN(prhs[4]) >= 1) {
    numangles = mxGetN(prhs[4]);
    angles = mxGetPr(prhs[4]);
    for (i = 0; i < numangles; i++)
      if (angles[i] <= 0 || angles[i] > 180) {
	mexErrMsgTxt("All angles must be between 0 and 180");
      }
  } else {
    numangles = 1;
    angles = (double *)mxCalloc(numangles,sizeof(double));
    angles[0] = 180;
  }

  /* Argument #5: the number of wedges in one quarter of the circle */
  nwedges = (nrhs >= 6) ? mxGetScalar(prhs[5]) : 6;
  if (nwedges * 2 > MAXWEDGES)
    mexErrMsgTxt("Too many wedges");
  
  wedgeangle = 90.0 / nwedges;
  for (i = 0; i < numangles; i++)
    if (angles[i]/wedgeangle != floor(angles[i]/wedgeangle))
      mexErrMsgTxt("Angles chosen not compatible with number of wedges");

  /* Argument #6: the maximum number of clusters in a color signature */
  if (nrhs >= 7 && mxGetN(prhs[6]) > 1)
    if (mxGetN(prhs[6]) == numsigmas)
      maxclusters = mxGetPr(prhs[6]);
    else
      mexErrMsgTxt("Maxclusters must be a scalar or equal to # of sigmas");
  else { 
    maxclusters = (double *)mxCalloc(numsigmas,sizeof(double));
    for (i = 0; i < numsigmas; i++) {
      maxclusters[i] = (nrhs >= 7) ? mxGetScalar(prhs[6]) : DEFAULTCLUSTERS;
      if (maxclusters[i] > MAXCLUSTERS)
	mexErrMsgTxt("Maximum number of clusters greater than allowed");
    }
  }

  /* Allocate output arguments */
  for (i = 0; i < nlhs; i++) {
    if (i == STRENGTH && plot == 1) { /* Allocate compass plots */
      if (numsigmas == 1 && numangles == 1) {
	dims[0] = (int)(dimensions[2] - dimensions[0])/(int)spacing[0] + 1;
	dims[1] = (int)(dimensions[3] - dimensions[1])/(int)spacing[0] + 1;
	dims[2] = (angles[0] == 180) ? 2 * nwedges : 4 * nwedges; 
	plhs[STRENGTH] = mxCreateNumericArray(3, dims, mxDOUBLE_CLASS, mxREAL);
      } else { /* Create a list of compass plots */
	plhs[STRENGTH] = mxCreateCellMatrix(numangles, numsigmas);
	for (j = 0; j < numsigmas; j++) {
	  dims[0] = (int)(dimensions[2] - dimensions[0])/(int)spacing[j] + 1;
	  dims[1] = (int)(dimensions[3] - dimensions[1])/(int)spacing[j] + 1;
	  for (k = 0; k < numangles; k++) {
	    dims[2] = (angles[k] == 180) ? 2 * nwedges : 4 * nwedges;
	    mxSetCell(plhs[STRENGTH], j * numangles + k, 
		      mxCreateNumericArray(3, dims, mxDOUBLE_CLASS, mxREAL));
	  }
	}
      }
    } else {
      /* Allow multiple pages for uncertainty and orientation */
      dims[2] = (i == STRENGTH || i == ABNORMALITY) ? 1 : MAXRESPONSES;
      if (numsigmas == 1 && numangles == 1) { /* One matrix per argument */
	dims[0] = (int)(dimensions[2] - dimensions[0])/(int)spacing[0] + 1;
	dims[1] = (int)(dimensions[3] - dimensions[1])/(int)spacing[0] + 1;
	plhs[i] = mxCreateNumericArray(3, dims, mxDOUBLE_CLASS, mxREAL);
      } else { /* Create a list for each argument */
	plhs[i] = mxCreateCellMatrix(numangles, numsigmas);
	for (j = 0; j < numsigmas; j++) {
	  dims[0] = (int)(dimensions[2] - dimensions[0])/(int)spacing[j] + 1;
	  dims[1] = (int)(dimensions[3] - dimensions[1])/(int)spacing[j] + 1;
	  for (k = 0; k < numangles; k++) 
	    mxSetCell(plhs[i], j * numangles + k, mxCreateNumericArray(3,
                      dims, mxDOUBLE_CLASS, mxREAL));
	}
      }
    }
  }
  switch (nlhs) {  /* This has no breaks; be careful when modifying */
  case 4: 
    uncertainty = (mxArray **)mxCalloc(numsigmas*numangles,sizeof(mxArray *));
    if (numsigmas == 1 && numangles == 1)
      uncertainty[0] = plhs[UNCERTAINTY];
    else
      for (i = 0; i < numsigmas * numangles; i++)
	uncertainty[i] = mxGetCell(plhs[UNCERTAINTY],i);
  case 3: 
    abnormality = (mxArray **)mxCalloc(numsigmas*numangles,sizeof(mxArray *));
    if (numsigmas == 1 && numangles == 1)
      abnormality[0] = plhs[ABNORMALITY];
    else
      for (i = 0; i < numsigmas * numangles; i++)
	abnormality[i] = mxGetCell(plhs[ABNORMALITY],i);
  case 2: 
    orientation = (mxArray **)mxCalloc(numsigmas*numangles,sizeof(mxArray *));
    if (numsigmas == 1 && numangles == 1)
      orientation[0] = plhs[ORIENTATION];
    else
      for (i = 0; i < numsigmas * numangles; i++)
	orientation[i] = mxGetCell(plhs[ORIENTATION],i);
  case 1: 
    strength = (mxArray **)mxCalloc(numsigmas*numangles,sizeof(mxArray *));
    if (numsigmas == 1 && numangles == 1)
      strength[0] = plhs[STRENGTH];
    else
      for (i = 0; i < numsigmas * numangles; i++)
	strength[i] = mxGetCell(plhs[STRENGTH],i);
  }

  Compass(imgdata, imgrows, imgcols, type, sigmas, numsigmas, maxradius, 
	  spacing, dimensions, angles, numangles, nwedges, maxclusters, plot,
	  strength, abnormality, orientation, uncertainty);
}
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
    //-----------------------
    // Input pointers
    
    double		    *h_fMRI_Volumes_double, *h_Quadrature_Filter_1_Real_double, *h_Quadrature_Filter_2_Real_double, *h_Quadrature_Filter_3_Real_double, *h_Quadrature_Filter_1_Imag_double, *h_Quadrature_Filter_2_Imag_double, *h_Quadrature_Filter_3_Imag_double;
    float           *h_fMRI_Volumes, *h_Quadrature_Filter_1_Real, *h_Quadrature_Filter_2_Real, *h_Quadrature_Filter_3_Real, *h_Quadrature_Filter_1_Imag, *h_Quadrature_Filter_2_Imag, *h_Quadrature_Filter_3_Imag;
    int             MOTION_CORRECTION_FILTER_SIZE, NUMBER_OF_ITERATIONS_FOR_MOTION_CORRECTION;
    int             OPENCL_PLATFORM,OPENCL_DEVICE;
    float           EPI_VOXEL_SIZE_X, EPI_VOXEL_SIZE_Y, EPI_VOXEL_SIZE_Z;
    
    //-----------------------
    // Output pointers        
    
    double     		*h_Motion_Corrected_fMRI_Volumes_double, *h_Motion_Parameters_double;
    float           *h_Motion_Corrected_fMRI_Volumes, *h_Motion_Parameters;
    
    //---------------------
    
    /* Check the number of input and output arguments. */
    if(nrhs<10)
    {
        mexErrMsgTxt("Too few input arguments.");
    }
    if(nrhs>10)
    {
        mexErrMsgTxt("Too many input arguments.");
    }
    if(nlhs<2)
    {
        mexErrMsgTxt("Too few output arguments.");
    }
    if(nlhs>2)
    {
        mexErrMsgTxt("Too many output arguments.");
    }
    
    /* Input arguments */
    
    // The data
    h_fMRI_Volumes_double =  (double*)mxGetData(prhs[0]);
    EPI_VOXEL_SIZE_X = (float)mxGetScalar(prhs[1]);
    EPI_VOXEL_SIZE_Y = (float)mxGetScalar(prhs[2]);
    EPI_VOXEL_SIZE_Z = (float)mxGetScalar(prhs[3]);
    h_Quadrature_Filter_1_Real_double =  (double*)mxGetPr(prhs[4]);
    h_Quadrature_Filter_1_Imag_double =  (double*)mxGetPi(prhs[4]);
    h_Quadrature_Filter_2_Real_double =  (double*)mxGetPr(prhs[5]);
    h_Quadrature_Filter_2_Imag_double =  (double*)mxGetPi(prhs[5]);
    h_Quadrature_Filter_3_Real_double =  (double*)mxGetPr(prhs[6]);
    h_Quadrature_Filter_3_Imag_double =  (double*)mxGetPi(prhs[6]);
    NUMBER_OF_ITERATIONS_FOR_MOTION_CORRECTION  = (int)mxGetScalar(prhs[7]);
    OPENCL_PLATFORM  = (int)mxGetScalar(prhs[8]);
    OPENCL_DEVICE  = (int)mxGetScalar(prhs[9]);
    
    int NUMBER_OF_DIMENSIONS = mxGetNumberOfDimensions(prhs[0]);
    const int *ARRAY_DIMENSIONS_DATA = mxGetDimensions(prhs[0]);
    const int *ARRAY_DIMENSIONS_FILTER = mxGetDimensions(prhs[4]);
    
    int DATA_H, DATA_W, DATA_D, DATA_T, NUMBER_OF_MOTION_CORRECTION_PARAMETERS;
    NUMBER_OF_MOTION_CORRECTION_PARAMETERS = 6;
    
    DATA_H = ARRAY_DIMENSIONS_DATA[0];
    DATA_W = ARRAY_DIMENSIONS_DATA[1];
    DATA_D = ARRAY_DIMENSIONS_DATA[2];
    DATA_T = ARRAY_DIMENSIONS_DATA[3];
                
    MOTION_CORRECTION_FILTER_SIZE = ARRAY_DIMENSIONS_FILTER[0];
            
    int DATA_SIZE = DATA_W * DATA_H * DATA_D * DATA_T * sizeof(float);
    int MOTION_PARAMETERS_SIZE = NUMBER_OF_MOTION_CORRECTION_PARAMETERS * DATA_T * sizeof(float);
    int FILTER_SIZE = MOTION_CORRECTION_FILTER_SIZE * MOTION_CORRECTION_FILTER_SIZE * MOTION_CORRECTION_FILTER_SIZE * sizeof(float);
    int VOLUME_SIZE = DATA_W * DATA_H * DATA_D * sizeof(float);
    
    mexPrintf("Data size : %i x %i x %i x %i \n",  DATA_W, DATA_H, DATA_D, DATA_T);
    mexPrintf("Voxel size : %f x %f x %f \n",  EPI_VOXEL_SIZE_X, EPI_VOXEL_SIZE_Y, EPI_VOXEL_SIZE_Z);
    mexPrintf("Filter size : %i x %i x %i \n",  MOTION_CORRECTION_FILTER_SIZE,MOTION_CORRECTION_FILTER_SIZE,MOTION_CORRECTION_FILTER_SIZE);
    mexPrintf("Number of iterations : %i \n",  NUMBER_OF_ITERATIONS_FOR_MOTION_CORRECTION);
    
    //-------------------------------------------------
    // Output to Matlab
    
    // Create pointer for volumes to Matlab        
    NUMBER_OF_DIMENSIONS = 4;
    int ARRAY_DIMENSIONS_OUT_MOTION_CORRECTED_FMRI_VOLUMES[4];
    ARRAY_DIMENSIONS_OUT_MOTION_CORRECTED_FMRI_VOLUMES[0] = DATA_H;
    ARRAY_DIMENSIONS_OUT_MOTION_CORRECTED_FMRI_VOLUMES[1] = DATA_W;
    ARRAY_DIMENSIONS_OUT_MOTION_CORRECTED_FMRI_VOLUMES[2] = DATA_D;
    ARRAY_DIMENSIONS_OUT_MOTION_CORRECTED_FMRI_VOLUMES[3] = DATA_T;
    
    plhs[0] = mxCreateNumericArray(NUMBER_OF_DIMENSIONS,ARRAY_DIMENSIONS_OUT_MOTION_CORRECTED_FMRI_VOLUMES,mxDOUBLE_CLASS, mxREAL);
    h_Motion_Corrected_fMRI_Volumes_double = mxGetPr(plhs[0]);          
    
    NUMBER_OF_DIMENSIONS = 2;
    int ARRAY_DIMENSIONS_OUT_MOTION_PARAMETERS[2];
    ARRAY_DIMENSIONS_OUT_MOTION_PARAMETERS[0] = DATA_T;
    ARRAY_DIMENSIONS_OUT_MOTION_PARAMETERS[1] = NUMBER_OF_MOTION_CORRECTION_PARAMETERS;    
    
    plhs[1] = mxCreateNumericArray(NUMBER_OF_DIMENSIONS,ARRAY_DIMENSIONS_OUT_MOTION_PARAMETERS,mxDOUBLE_CLASS, mxREAL);
    h_Motion_Parameters_double = mxGetPr(plhs[1]);          
        
    // ------------------------------------------------
    
    // Allocate memory on the host
    h_fMRI_Volumes                         = (float *)mxMalloc(DATA_SIZE);
    h_Quadrature_Filter_1_Real             = (float *)mxMalloc(FILTER_SIZE);
    h_Quadrature_Filter_1_Imag             = (float *)mxMalloc(FILTER_SIZE);
    h_Quadrature_Filter_2_Real             = (float *)mxMalloc(FILTER_SIZE);
    h_Quadrature_Filter_2_Imag             = (float *)mxMalloc(FILTER_SIZE);    
    h_Quadrature_Filter_3_Real             = (float *)mxMalloc(FILTER_SIZE);
    h_Quadrature_Filter_3_Imag             = (float *)mxMalloc(FILTER_SIZE);    
    h_Motion_Corrected_fMRI_Volumes        = (float *)mxMalloc(DATA_SIZE);
    h_Motion_Parameters                    = (float *)mxMalloc(MOTION_PARAMETERS_SIZE);    
    
    // Pack data (reorder from y,x,z to x,y,z and cast from double to float)
    pack_double2float_volumes(h_fMRI_Volumes, h_fMRI_Volumes_double, DATA_W, DATA_H, DATA_D, DATA_T);
    pack_double2float_volume(h_Quadrature_Filter_1_Real, h_Quadrature_Filter_1_Real_double, MOTION_CORRECTION_FILTER_SIZE, MOTION_CORRECTION_FILTER_SIZE, MOTION_CORRECTION_FILTER_SIZE);
    pack_double2float_volume(h_Quadrature_Filter_1_Imag, h_Quadrature_Filter_1_Imag_double, MOTION_CORRECTION_FILTER_SIZE, MOTION_CORRECTION_FILTER_SIZE, MOTION_CORRECTION_FILTER_SIZE);
    pack_double2float_volume(h_Quadrature_Filter_2_Real, h_Quadrature_Filter_2_Real_double, MOTION_CORRECTION_FILTER_SIZE, MOTION_CORRECTION_FILTER_SIZE, MOTION_CORRECTION_FILTER_SIZE);
    pack_double2float_volume(h_Quadrature_Filter_2_Imag, h_Quadrature_Filter_2_Imag_double, MOTION_CORRECTION_FILTER_SIZE, MOTION_CORRECTION_FILTER_SIZE, MOTION_CORRECTION_FILTER_SIZE);
    pack_double2float_volume(h_Quadrature_Filter_3_Real, h_Quadrature_Filter_3_Real_double, MOTION_CORRECTION_FILTER_SIZE, MOTION_CORRECTION_FILTER_SIZE, MOTION_CORRECTION_FILTER_SIZE);
    pack_double2float_volume(h_Quadrature_Filter_3_Imag, h_Quadrature_Filter_3_Imag_double, MOTION_CORRECTION_FILTER_SIZE, MOTION_CORRECTION_FILTER_SIZE, MOTION_CORRECTION_FILTER_SIZE);

    //------------------------
    
    BROCCOLI_LIB BROCCOLI(OPENCL_PLATFORM,OPENCL_DEVICE);
    
    // Something went wrong...
    if (BROCCOLI.GetOpenCLInitiated() == 0)
    {    
        printf("Initialization error is \"%s\" \n",BROCCOLI.GetOpenCLInitializationError());
        printf("OpenCL error is \"%s\" \n",BROCCOLI.GetOpenCLError());
        
        // Print create kernel errors
        int* createKernelErrors = BROCCOLI.GetOpenCLCreateKernelErrors();
        for (int i = 0; i < BROCCOLI.GetNumberOfOpenCLKernels(); i++)
        {
            if (createKernelErrors[i] != 0)
            {
                mexPrintf("Create kernel error for kernel '%s' is '%s' \n",BROCCOLI.GetOpenCLKernelName(i),BROCCOLI.GetOpenCLErrorMessage(createKernelErrors[i]));
            }
        }                
        
        mexPrintf("OPENCL initialization failed, aborting \n");        
        
        // Print build info
        mexPrintf("Build info \n \n %s \n", BROCCOLI.GetOpenCLBuildInfoChar());      
    }
    else if (BROCCOLI.GetOpenCLInitiated() == 1)
    {
        BROCCOLI.SetEPIWidth(DATA_W);
        BROCCOLI.SetEPIHeight(DATA_H);
        BROCCOLI.SetEPIDepth(DATA_D);
        BROCCOLI.SetEPITimepoints(DATA_T);   
        
        BROCCOLI.SetEPIVoxelSizeX(EPI_VOXEL_SIZE_X);
        BROCCOLI.SetEPIVoxelSizeY(EPI_VOXEL_SIZE_Y);
        BROCCOLI.SetEPIVoxelSizeZ(EPI_VOXEL_SIZE_Z);
        
        BROCCOLI.SetInputfMRIVolumes(h_fMRI_Volumes);
        BROCCOLI.SetImageRegistrationFilterSize(MOTION_CORRECTION_FILTER_SIZE);
        BROCCOLI.SetLinearImageRegistrationFilters(h_Quadrature_Filter_1_Real, h_Quadrature_Filter_1_Imag, h_Quadrature_Filter_2_Real, h_Quadrature_Filter_2_Imag, h_Quadrature_Filter_3_Real, h_Quadrature_Filter_3_Imag);
        BROCCOLI.SetNumberOfIterationsForMotionCorrection(NUMBER_OF_ITERATIONS_FOR_MOTION_CORRECTION);
        BROCCOLI.SetOutputMotionCorrectedfMRIVolumes(h_Motion_Corrected_fMRI_Volumes);
        BROCCOLI.SetOutputMotionParameters(h_Motion_Parameters);
             
        BROCCOLI.PerformMotionCorrectionWrapper();        
    
        // Print create buffer errors
        int* createBufferErrors = BROCCOLI.GetOpenCLCreateBufferErrors();
        for (int i = 0; i < BROCCOLI.GetNumberOfOpenCLKernels(); i++)
        {
            if (createBufferErrors[i] != 0)
            {
                mexPrintf("Create buffer error %i is %d \n",i,createBufferErrors[i]);
            }
        }

        // Print create kernel errors
        int* createKernelErrors = BROCCOLI.GetOpenCLCreateKernelErrors();
        for (int i = 0; i < BROCCOLI.GetNumberOfOpenCLKernels(); i++)
        {
            if (createKernelErrors[i] != 0)
            {
                mexPrintf("Create kernel error for kernel '%s' is '%s' \n",BROCCOLI.GetOpenCLKernelName(i),BROCCOLI.GetOpenCLErrorMessage(createKernelErrors[i]));
            }
        }                

        // Print run kernel errors
        int* runKernelErrors = BROCCOLI.GetOpenCLRunKernelErrors();
        for (int i = 0; i < BROCCOLI.GetNumberOfOpenCLKernels(); i++)
        {
            if (runKernelErrors[i] != 0)
            {
                mexPrintf("Run kernel error for kernel '%s' is '%s' \n",BROCCOLI.GetOpenCLKernelName(i),BROCCOLI.GetOpenCLErrorMessage(runKernelErrors[i]));
            }
        } 
    }
    
    // Unpack results to Matlab
    unpack_float2double_volumes(h_Motion_Corrected_fMRI_Volumes_double, h_Motion_Corrected_fMRI_Volumes, DATA_W, DATA_H, DATA_D, DATA_T);
    unpack_float2double(h_Motion_Parameters_double, h_Motion_Parameters, NUMBER_OF_MOTION_CORRECTION_PARAMETERS * DATA_T);
    
    // Free all the allocated memory on the host
    mxFree(h_fMRI_Volumes);
    mxFree(h_Quadrature_Filter_1_Real);
    mxFree(h_Quadrature_Filter_1_Imag);
    mxFree(h_Quadrature_Filter_2_Real);
    mxFree(h_Quadrature_Filter_2_Imag);
    mxFree(h_Quadrature_Filter_3_Real);
    mxFree(h_Quadrature_Filter_3_Imag);
    mxFree(h_Motion_Corrected_fMRI_Volumes); 
    mxFree(h_Motion_Parameters);        
    
    return;
}
void mexFunction(int nlhs, mxArray *plhs[],
  int nrhs, const mxArray *prhs[])
{
  char me[]="nrrdLoad", *filename, *errPtr, errBuff[AIR_STRLEN_MED];
  int filenameLen, sizeI[NRRD_DIM_MAX];
  mxClassID mtype;
  size_t sizeZ[NRRD_DIM_MAX];
  unsigned int axIdx;
  Nrrd *nrrd;
  NrrdIoState *nio;
  airArray *mop;

  if (!(1 == nrhs && mxIsChar(prhs[0]))) {
    sprintf(errBuff, "%s: requires one string argument (the name of the file)", me);
    mexErrMsgTxt(errBuff);
  }

  mop = airMopNew();
  filenameLen = mxGetM(prhs[0])*mxGetN(prhs[0])+1;
  filename = mxCalloc(filenameLen, sizeof(mxChar));  /* managed by Matlab */
  mxGetString(prhs[0], filename, filenameLen);

  nrrd = nrrdNew();
  airMopAdd(mop, nrrd, (airMopper)nrrdNix, airMopAlways);
  nio = nrrdIoStateNew();
  airMopAdd(mop, nio, (airMopper)nrrdIoStateNix, airMopAlways);
  nrrdIoStateSet(nio, nrrdIoStateSkipData, AIR_TRUE);

  /* read header, but no data */
  if (nrrdLoad(nrrd, filename, nio)) {
    errPtr = biffGetDone(NRRD);
    airMopAdd(mop, errPtr, airFree, airMopAlways);
    sprintf(errBuff, "%s: trouble reading NRRD header:\n%s", me, errPtr);
    airMopError(mop);
    mexErrMsgTxt(errBuff);
  }
  mtype = typeNtoM(nrrd->type);
  if (mxUNKNOWN_CLASS == mtype) {
    sprintf(errBuff, "%s: sorry, can't handle type %s (%d)", me,
            airEnumStr(nrrdType, nrrd->type), nrrd->type);
    airMopError(mop);
    mexErrMsgTxt(errBuff);
  }

  /* allocate matlab array based on nrrd struct */
  for (axIdx=0; axIdx<nrrd->dim; axIdx++) {
    sizeI[axIdx] = nrrd->axis[axIdx].size;
  }
  plhs[0]=mxCreateNumericArray(nrrd->dim,sizeI,mtype,mxREAL);

  /* copy data pointer */
  nrrd->data = mxGetPr(plhs[0]);

  /* read second time, now loading data */
  if (nrrdLoad(nrrd, filename, NULL)) {
    errPtr = biffGetDone(NRRD);
    airMopAdd(mop, errPtr, airFree, airMopAlways);
    sprintf(errBuff, "%s: trouble reading NRRD:\n%s", me, errPtr);
    airMopError(mop);
    mexErrMsgTxt(errBuff);
  }

  airMopOkay(mop);
  return;
}
Example #20
0
File: read.c Project: bitursa/maos
static mxArray *readdata(file_t *fp, mxArray **header, int start, int howmany){
    /*
      if start!=0 || howmany!=0 and data is cell, will only read cell from start to start+howmany
      if data is not cell and start==-1, will skip the data.
      Only the first call to readdata will possibly have howmany!=0
     */
    if(fp->eof) return NULL;
    header_t header2;
    if(read_header2(&header2, fp)){
	return NULL;
    }
    uint32_t magic=header2.magic & 0xFFFF;
    if(magic==0){//end of file or empty file
	fp->eof=1;
	return NULL;
    }
    if(header){
	if(header2.str)
	    *header=mxCreateString(header2.str);
	else
	    *header=mxCreateString("");
    }
    free(header2.str); header2.str=NULL;
    long nx=header2.nx;
    long ny=header2.ny;
    int start_save=start;
    if(iscell(magic)){
	if(start!=-1 && howmany==0){
	    if(start!=0){
		error("Invalid use\n");
	    }
	    howmany=nx*ny-start;
	}
    }else if(fp->isfits){
	if(howmany!=0){
	    /*first read of fits file. determine if we need it*/
	    if(start>0){
		start=-1;//skip this block.
	    }
	}
    }else{
	if((start!=0 && start!=-1) || howmany!=0){
	    error("invalid use");
	}
    }
    int iscell=0;
    if(fp->eof) return NULL;
    mxArray *out=NULL;
    switch(magic){
    case MCC_ANY:
    case MCC_DBL:
    case MCC_CMP:
    case MC_CSP:
    case MC_SP:
    case MC_DBL:
    case MC_CMP:
    case MC_INT32:
    case MC_INT64:
	{
	    iscell=1;
	    mwIndex ix;
	    if(fp->eof) return NULL;
	    if(nx*ny>1 && skip_unicell){
		out=mxCreateCellMatrix(nx,ny);
	    }
	    mxArray *header0=mxCreateCellMatrix(nx*ny+1,1);
	    for(ix=0; ix<nx*ny; ix++){
		int start2=0;
		if(start==-1 || ix<start || ix>=start+howmany){
		    start2=-1;
		}
		mxArray *header3=NULL;
		mxArray *tmp=readdata(fp, &header3, start2, 0);
		if(fp->eof){
		    break;
		}
		if(tmp && tmp!=SKIPPED){
		    if(nx*ny==1 && skip_unicell){//only one entry
			out=tmp;
		    }else{
			mxSetCell(out, ix, tmp);
		    }
		    if(header3){
			mxSetCell(header0, ix, header3);
		    }
		}
	    }
	    if(header){
		mxSetCell(header0, nx*ny, *header);
		*header=header0;
	    }
	}
	break;
    case M_SP64:
    case M_SP32:
	{
	    if(start==-1) error("Invalid use\n");
	    size_t size;
	    if(magic==M_SP32){
		size=4;
	    }else if(magic==M_SP64){
		size=8;
	    }else{
		size=0;
		error("Invalid magic\n");
	    }
	    uint64_t nzmax;
	    if(nx!=0 && ny!=0){
		zfread(&nzmax,sizeof(uint64_t),1,fp);
	    }else{
		nzmax=0;
	    }
	    if(fp->eof) return NULL;
	    out=mxCreateSparse(nx,ny,nzmax,mxREAL);
	    if(nx!=0 && ny!=0 && nzmax!=0){
		if(sizeof(mwIndex)==size){/*Match*/
		    zfread(mxGetJc(out), size,ny+1,fp);
		    zfread(mxGetIr(out), size,nzmax, fp);
		}else{
		    long i;
		    mwIndex *Jc0=mxGetJc(out);
		    mwIndex *Ir0=mxGetIr(out);
		    void *Jc=malloc(size*(ny+1));
		    void *Ir=malloc(size*nzmax);
		    zfread(Jc, size, ny+1, fp);
		    zfread(Ir, size, nzmax, fp);
		    if(size==4){
			uint32_t* Jc2=Jc;
			uint32_t* Ir2=Ir;
			for(i=0; i<ny+1; i++){
			    Jc0[i]=Jc2[i];
			}
			for(i=0; i<nzmax; i++){
			    Ir0[i]=Ir2[i];
			}
			free(Jc);
			free(Ir);
		    }else if(size==8){
			uint64_t* Jc2=Jc;
			uint64_t* Ir2=Ir;
			for(i=0; i<ny+1; i++){
			    Jc0[i]=Jc2[i];
			}
			for(i=0; i<nzmax; i++){
			    Ir0[i]=Ir2[i];
			}
			free(Jc);
			free(Ir);
		    }else{
			mexErrMsgTxt("Invalid sparse format\n");
		    }
		}
		zfread(mxGetPr(out), sizeof(double), nzmax, fp);
	    }
	}
	break;
    case M_CSP64:
    case M_CSP32:/*complex sparse*/
	{
	    if(start==-1) error("Invalid use\n");
	    size_t size;
	    switch(magic){
	    case M_CSP32:
		size=4;break;
	    case M_CSP64:
		size=8;break;
	    default:
		size=0;
	    }
	    uint64_t nzmax;
	    if(nx!=0 && ny!=0){
		zfread(&nzmax,sizeof(uint64_t),1,fp);
	    }else{
		nzmax=0;
	    }
	    if(fp->eof) return NULL;
	    out=mxCreateSparse(nx,ny,nzmax,mxCOMPLEX);
	    if(nx!=0 && ny!=0){
		long i;
		if(sizeof(mwIndex)==size){
		    zfread(mxGetJc(out), size,ny+1,fp);
		    zfread(mxGetIr(out), size,nzmax, fp);
		}else{
		    mwIndex *Jc0=mxGetJc(out);
		    mwIndex *Ir0=mxGetIr(out);
		    void *Jc=malloc(size*(ny+1));
		    void *Ir=malloc(size*nzmax);
		    zfread(Jc, size, ny+1, fp);
		    zfread(Ir, size, nzmax, fp);
		    if(size==4){
			uint32_t* Jc2=Jc;
			uint32_t* Ir2=Ir;
			for(i=0; i<ny+1; i++){
			    Jc0[i]=Jc2[i];
			}
			for(i=0; i<nzmax; i++){
			    Ir0[i]=Ir2[i];
			}
			free(Jc);
			free(Ir);
		    }else if(size==8){
			uint64_t* Jc2=Jc;
			uint64_t* Ir2=Ir;
			for(i=0; i<ny+1; i++){
			    Jc0[i]=Jc2[i];
			}
			for(i=0; i<nzmax; i++){
			    Ir0[i]=Ir2[i];
			}
			free(Jc);
			free(Ir);
		    }else{
			info("size=%lu\n", size);
			error("Invalid sparse format\n");
		    }
		}
		dcomplex *tmp=malloc(sizeof(dcomplex)*nzmax);
		zfread(tmp, sizeof(dcomplex), nzmax, fp);
		double *Pr=mxGetPr(out);
		double *Pi=mxGetPi(out);
		for(i=0; i<nzmax; i++){
		    Pr[i]=tmp[i].x;
		    Pi[i]=tmp[i].y;
		}
		free(tmp);
	    }
	}
	break;
    case M_DBL:/*double array*/
	if(start==-1){
	    if(zfseek(fp, sizeof(double)*nx*ny, SEEK_CUR)){
		error("Seek failed\n");
	    }
	    out=SKIPPED;
	}else{
	    out=mxCreateDoubleMatrix(nx,ny,mxREAL);
	    if(nx!=0 && ny!=0){
		zfread(mxGetPr(out), sizeof(double),nx*ny,fp);
	    }
	}
	break;
    case M_FLT:/*float array*/
	if(start==-1){
	    if(zfseek(fp, sizeof(float)*nx*ny, SEEK_CUR)){
		error("Seek failed\n");
	    }
	    out=SKIPPED;
	}else{
	    mwSize nxy[2]={nx,ny};
	    out=mxCreateNumericArray(2, nxy,mxSINGLE_CLASS, mxREAL);
	    if(nx!=0 && ny!=0){
		zfread((float*)mxGetPr(out), sizeof(float),nx*ny, fp);
	    }
	}break;
    case M_INT64:/*long array*/
    case M_INT32:
    case M_INT16:
    case M_INT8:
	{
	    int byte=0;
	    mxClassID id;
	    switch(magic){
	    case M_INT64: byte=8; id=mxINT64_CLASS; break;
	    case M_INT32: byte=4; id=mxINT32_CLASS; break;
	    case M_INT16: byte=2; id=mxINT16_CLASS; break;
	    case M_INT8:  byte=1; id=mxINT8_CLASS; break;
	    default: id=0;
	    }
	    if(start==-1){
		if(zfseek(fp, byte*nx*ny, SEEK_CUR)){
		    error("Seek failed\n");
		}
		out=SKIPPED;
	    }else{
		out=mxCreateNumericMatrix(nx,ny,id,mxREAL);
		if(nx!=0 && ny!=0){
		    /*Don't use sizeof(mxINT64_CLASS), it is just an integer, 
		      not a valid C type.*/
		    zfread(mxGetPr(out), byte,nx*ny,fp);
		}
	    }
	}
	break;
    case M_CMP:/*double complex array*/
	if(start==-1){
	    if(zfseek(fp, 16*nx*ny, SEEK_CUR)){
		error("Seek failed\n");
	    }
	    out=SKIPPED;
	}else{
	    out=mxCreateDoubleMatrix(nx,ny,mxCOMPLEX);
	    if(nx!=0 && ny!=0){
		dcomplex*tmp=malloc(sizeof(dcomplex)*nx*ny);
		zfread(tmp,sizeof(dcomplex),nx*ny,fp);
		double *Pr=mxGetPr(out);
		double *Pi=mxGetPi(out);
		long i;
		for(i=0; i<nx*ny; i++){
		    Pr[i]=tmp[i].x;
		    Pi[i]=tmp[i].y;
		}
		free(tmp);
	    }
	}
	break;
    case M_ZMP:/*float complex array. convert to double*/
	if(start==-1){
	    if(zfseek(fp, 8*nx*ny, SEEK_CUR)){
		error("Seek failed\n");
	    }
	    out=SKIPPED;
	}else{
	    mwSize nxy[2]={nx, ny};
	    out=mxCreateNumericArray(2, nxy,mxSINGLE_CLASS, mxCOMPLEX);
	    if(nx!=0 && ny!=0){
		fcomplex*tmp=malloc(sizeof(fcomplex)*nx*ny);
		zfread(tmp,sizeof(fcomplex),nx*ny,fp);
		float *Pr=(float*)mxGetPr(out);
		float *Pi=(float*)mxGetPi(out);
		long i;
		for(i=0; i<nx*ny; i++){
		    Pr[i]=tmp[i].x;
		    Pi[i]=tmp[i].y;
		}
		free(tmp);
	    }
	}
	break;
    case M_HEADER:
	break;
    default:
	fprintf(stderr,"magic=%x\n",magic);
	warning("Unrecognized file. Please recompile the mex routines in the newest code\n");
	out=NULL;
    }
    start=start_save;
    if(!iscell && fp->isfits==1){/*fits file may contain extra extensions.*/
	fp->isfits++;
	int icell=0;
	mxArray **outarr=NULL;
	mxArray **headerarr=NULL;
	while(out){
	    icell++;
	    outarr=realloc(outarr, sizeof(mxArray*)*icell);
	    headerarr=realloc(headerarr, sizeof(mxArray*)*icell);
	    if(out==SKIPPED) out=NULL;
	    outarr[icell-1]=out;
	    if(header) headerarr[icell-1]=*header;
	    int start2=0;
	    if(howmany!=0){//selective reading.
		if(icell<start || icell+1>start+howmany){
		    start2=-1;//don't read next data.
		}
	    }
	    out=readdata(fp, header, start2, 0);
	}
	if(icell>1){/*set output.*/
	    out=mxCreateCellMatrix(icell, 1);
	    if(header) *header=mxCreateCellMatrix(icell, 1);
	    int i;
	    for(i=0; i<icell; i++){
		mxSetCell(out, i, outarr[i]);
		if(header) mxSetCell(*header, i, headerarr[i]);
	    }
	    free(outarr);
	    free(headerarr);
	}else{
	    out=outarr[0];
	    if(header) *header=headerarr[0];
	}
    }
    if(!out){
	out=mxCreateDoubleMatrix(0,0,mxREAL);
    }
    return out;
}
Example #21
0
//compact B
void mexFunction(int nlhs, mxArray *plhs[], 
				 int nrhs, const mxArray *prhs[])
{
	int num_thd = omp_get_num_procs();
	omp_set_num_threads(num_thd);

	SMART_ASSERT(nrhs == 4).Exit();

	SMatrix<double> matZ;
	Vector<SMatrix<double> > vecmatDictionary;
	int num_dic;

	mexConvert(MAT_Z, matZ);
	mexConvert(MAT_DIC, vecmatDictionary);
	mexConvert(N_SPARSITY, num_dic);
	SMART_ASSERT(num_dic > 0)(num_dic).Exit();

	int num_partitions = vecmatDictionary.size();

	mwSize size[2];
	size[0] = num_dic * num_partitions;
	size[1] = matZ.Rows();

	//BINARY_REPRESENTATION = mxCreateNumericArray(2, size, mxINT16_CLASS, mxREAL);
	BINARY_REPRESENTATION = mxCreateNumericArray(2, size, mxUINT8_CLASS, mxREAL);
	SMatrix<CodeType> matRepresentation;
	mexConvert(BINARY_REPRESENTATION, matRepresentation);

	// method:
	// 2: ock-means described in the paper
	// others: jck-means
	IndexEncoding mp;

	if (num_dic > 1)
	{
		SMART_ASSERT(mxIsEmpty(PARAMETER) == false).Exit();

		int is_initialize;
		int num_grouped;
		mexConvert(mxGetField(PARAMETER, 0, "is_initialize"), is_initialize);;


		TypeEncoding type_encoding = Type_gk_means;
		int is_ock = 0;
		{
			mxArray* p2 = mxGetField(PARAMETER, 0, "is_ock");
			if (p2)
			{

				mexConvert(p2, is_ock);
				if (is_ock)
				{
					type_encoding = Type_ock;
				}
			}
		}
		{
			mxArray* p2 = mxGetField(PARAMETER, 0, "encoding_type");
			if (p2)
			{
				string str_encoding_type;
				mexConvert(p2, str_encoding_type);

				{
					if (is_ock)
					{
						SMART_ASSERT(str_encoding_type == "ock").Exit();
					}
				}

				if (str_encoding_type == "gkmeans")
				{
					mp.SetEncodingType(Type_gk_means);
					mexConvert(mxGetField(PARAMETER, 0, "num_grouped"), num_grouped);
					mp.SetNumberGroup(num_grouped);
				}
				else if (str_encoding_type == "ock")
				{
					mp.SetEncodingType(Type_ock);
					int num_can;
					mexConvert(mxGetField(PARAMETER, 0, "num_can"), num_can);
					mp.SetCandidateNumber(num_can);
				}
				else if (str_encoding_type == "additive_quantization")
				{
					mp.SetEncodingType(Type_additive_quantization);
					int num_can;
					mexConvert(mxGetField(PARAMETER, 0, "num_can"), num_can);
					mp.SetCandidateNumber(num_can);
				}
				else
				{
					SMART_ASSERT(0)(str_encoding_type).Exit();
				}
			}
		}

		mp.SetIsInitialize(is_initialize);

		if (!is_initialize)
		{
			SMatrix<CodeType> mat_old;
			mexConvert(mxGetField(PARAMETER, 0, "old_codes"), mat_old);
			memcpy(matRepresentation.Ptr(), mat_old.Ptr(), sizeof(CodeType) * mat_old.Rows() * mat_old.Cols());
		}
	}

	mp.Solve(matZ, vecmatDictionary, num_dic, matRepresentation);
}
Example #22
0
void mexFunction
(
    /* === Parameters ======================================================= */

    int nlhs,			/* number of left-hand sides */
    mxArray *plhs [],		/* left-hand side matrices */
    int nrhs,			/* number of right--hand sides */
    const mxArray *prhs []	/* right-hand side matrices */
)
{
    Zmat A;
    ZAMGlevelmat *PRE;
    ZILUPACKparam *param;
    integer n;

    const char **fnames;

    const mwSize  *dims;
    mxClassID  *classIDflags;
    mxArray    *tmp, *fout, *A_input , *b_input, *x0_input, *options_input, 
               *PRE_input, *options_output, *x_output;
    char       *pdata, *input_buf, *output_buf;
    mwSize     ndim,nnz, buflen;
    mwIndex    *irs, *jcs;
    int        ifield, status, nfields, ierr,i,j,k,l,m;
    size_t     mrows, ncols, sizebuf;
    double     dbuf, *A_valuesR, *A_valuesI, *convert, *sr, *pr, *pi;
    doublecomplex *sol, *rhs;
    mwIndex    *A_ja,                 /* row indices of input matrix A */
               *A_ia;                 /* column pointers of input matrix A */
    

    if (nrhs != 5)
       mexErrMsgTxt("five input arguments required.");
    else if (nlhs !=2)
       mexErrMsgTxt("Too many output arguments.");
    else if (!mxIsStruct(prhs[2]))
       mexErrMsgTxt("Third input must be a structure.");
    else if (!mxIsNumeric(prhs[0]))
       mexErrMsgTxt("First input must be a matrix.");

    /* The first input must be a square matrix.*/
    A_input = (mxArray *) prhs [0] ;
    /* get size of input matrix A */
    mrows = mxGetM (A_input) ;
    ncols = mxGetN (A_input) ;
    nnz = mxGetNzmax(A_input);
    if (mrows!=ncols) {
       mexErrMsgTxt("First input must be a square matrix.");
    }
    if (!mxIsSparse (A_input))
    {
        mexErrMsgTxt ("ILUPACK: input matrix must be in sparse format.") ;
    }





    /* copy input matrix to sparse row format */
    A.nc=A.nr=mrows;
    A.ia=(integer *) MAlloc((size_t)(A.nc+1)*sizeof(integer),"ZGNLHPDilupacksolver");
    A.ja=(integer *) MAlloc((size_t)nnz     *sizeof(integer),"ZGNLHPDilupacksolver");
    A. a=(doublecomplex *) MAlloc((size_t)nnz     *sizeof(doublecomplex), "ZGNLHPDilupacksolver");

    A_ja         = (mwIndex *)mxGetIr (A_input);
    A_ia         = (mwIndex *)mxGetJc (A_input);
    A_valuesR    = (double *) mxGetPr(A_input);
    if (mxIsComplex(A_input)) 
       A_valuesI = (double *) mxGetPi(A_input);

    /* -------------------------------------------------------------------- */
    /* ..  Convert matrix from 0-based C-notation to Fortran 1-based        */
    /*     notation.                                                        */
    /* -------------------------------------------------------------------- */

    /*
    for (i = 0 ; i < ncols ; i++)
      for (j = A_ia[i] ; j < A_ia[i+1] ; j++)
	printf("i=%d j=%d  A.real=%e\n", i+1,  A_ja[j]+1, A_valuesR[j]);
    */

    for (i=0; i<=A.nr; i++)
        A.ia[i]=0;
    /* remember that MATLAB uses storage by columns and NOT by rows! */
    for (i=0; i<A.nr; i++) {
	for (j=A_ia[i]; j<A_ia[i+1]; j++) {
	    k=A_ja[j];
	    A.ia[k+1]++;
	}
    }
    /* now we know how many entries are located in every row */

    /* switch to pointer structure */
    for (i=0; i<A.nr; i++) 
        A.ia[i+1]+=A.ia[i];

    if (mxIsComplex(A_input)) {
       for (i=0; i<ncols; i++) {
	   for (j=A_ia[i]; j<A_ia[i+1]; j++) {
	       /* row index l in C-notation */
	       l=A_ja[j];
	       /* where does row l currently start */
	       k=A.ia[l];
	       /* column index will be i in FORTRAN notation */
	       A.ja[k]=i+1;
	       A.a [k].r  =A_valuesR[j];
	       A.a [k++].i=A_valuesI[j];
	       A.ia[l]=k; 
	   }
       }
    }
    else {
       for (i=0; i<ncols; i++) {
	   for (j=A_ia[i]; j<A_ia[i+1]; j++) {
	       /* row index l in C-notation */
	       l=A_ja[j];
	       /* where does row l currently start */
	       k=A.ia[l];
	       /* column index will be i in FORTRAN notation */
	       A.ja[k]=i+1;
	       A.a [k].r  =A_valuesR[j];
	       A.a [k++].i=0;
	       A.ia[l]=k; 
	   }
       }
    }

    /* switch to FORTRAN style */
    for (i=A.nr; i>0; i--) 
        A.ia[i]=A.ia[i-1]+1;
    A.ia[0]=1;


    /*
    for (i = 0 ; i < A.nr ; i++)
      for (j = A.ia[i]-1 ; j < A.ia[i+1]-1 ; j++)
	  printf("i=%d j=%d  A.real=%e  A.imag=%e\n", i+1,  A.ja[j], A.a[j].r, A.a[j].i);
    */

    /* import pointer to the preconditioner */
    PRE_input = (mxArray*) prhs [1] ;
    /* get number of levels of input preconditioner structure `PREC' */
    /* nlev=mxGetN(PRE_input); */

    nfields = mxGetNumberOfFields(PRE_input);
    /* allocate memory  for storing pointers */
    fnames = mxCalloc((size_t)nfields, (size_t)sizeof(*fnames));
    for (ifield = 0; ifield < nfields; ifield++) {
        fnames[ifield] = mxGetFieldNameByNumber(PRE_input,ifield);
	/* check whether `PREC.ptr' exists */
	if (!strcmp("ptr",fnames[ifield])) {
	   /* field `ptr' */
	   tmp = mxGetFieldByNumber(PRE_input,0,ifield);
	   pdata = mxGetData(tmp);
	   memcpy(&PRE, pdata, (size_t)sizeof(size_t));
	}
	else if (!strcmp("param",fnames[ifield])) {
	   /* field `param' */
	   tmp = mxGetFieldByNumber(PRE_input,0,ifield);
	   pdata = mxGetData(tmp);
	   memcpy(&param, pdata, (size_t)sizeof(size_t));
	}
    }
    mxFree(fnames);

    /* rescale input matrix */
    /* obsolete
    for (i=0; i <A.nr; i++) {
	for (j=A.ia[i]-1; j<A.ia[i+1]-1; j++) {
	    A.a[j].r*=PRE->rowscal[i].r*PRE->colscal[A.ja[j]-1].r;
	    A.a[j].i*=PRE->rowscal[i].r*PRE->colscal[A.ja[j]-1].r;
	}
    }
    */

    /* Get third input argument `options' */
    options_input=(mxArray*)prhs[2];
    nfields = mxGetNumberOfFields(options_input);

    /* Allocate memory  for storing classIDflags */
    classIDflags = (mxClassID *) mxCalloc((size_t)nfields+1, (size_t)sizeof(mxClassID));
    
    /* allocate memory  for storing pointers */
    fnames = mxCalloc((size_t)nfields+1, (size_t)sizeof(*fnames));

    /* Get field name pointers */
    j=-1;
    for (ifield = 0; ifield < nfields; ifield++) {
        fnames[ifield] = mxGetFieldNameByNumber(options_input,ifield);
	/* check whether `options.niter' already exists */
	if (!strcmp("niter",fnames[ifield]))
	   j=ifield;
    }
    if (j==-1)
       fnames[nfields]="niter";
    /* mexPrintf("search for niter completed\n"); fflush(stdout); */


    /* import data */
    for (ifield = 0; ifield < nfields; ifield++) {
        /* mexPrintf("%2d\n",ifield+1); fflush(stdout); */
	tmp = mxGetFieldByNumber(options_input,0,ifield);
	classIDflags[ifield] = mxGetClassID(tmp); 

	ndim = mxGetNumberOfDimensions(tmp);
	dims = mxGetDimensions(tmp);

	/* Create string/numeric array */
	if (classIDflags[ifield] == mxCHAR_CLASS) {
	   /* Get the length of the input string. */
	   buflen = (mxGetM(tmp) * mxGetN(tmp)) + 1;

	   /* Allocate memory for input and output strings. */
	   input_buf = (char *) mxCalloc((size_t)buflen, (size_t)sizeof(char));

	   /* Copy the string data from tmp into a C string 
	      input_buf. */
	   status = mxGetString(tmp, input_buf, buflen);
	   
	   if (!strcmp("amg",fnames[ifield])) {
              if (strcmp(param->amg,input_buf)) {
		 param->amg=(char *)MAlloc((size_t)buflen*sizeof(char),"ilupacksolver");
		 strcpy(param->amg,input_buf);
	      }
	   }
	   else if (!strcmp("presmoother",fnames[ifield])) {
              if (strcmp(param->presmoother,input_buf)) {
		 param->presmoother=(char *)MAlloc((size_t)buflen*sizeof(char),
						   "ilupacksolver");
		 strcpy(param->presmoother,input_buf);
	      }
	   }
	   else if (!strcmp("postsmoother",fnames[ifield])) {
              if (strcmp(param->postsmoother,input_buf)) {
		 param->postsmoother=(char *)MAlloc((size_t)buflen*sizeof(char),
						    "ilupacksolver");
		 strcpy(param->postsmoother,input_buf);
	      }
	   }
	   else if (!strcmp("typecoarse",fnames[ifield])) {
              if (strcmp(param->typecoarse,input_buf)) {
		 param->typecoarse=(char *)MAlloc((size_t)buflen*sizeof(char),
						  "ilupacksolver");
		 strcpy(param->typecoarse,input_buf);
	      }
	   }
	   else if (!strcmp("typetv",fnames[ifield])) {
              if (strcmp(param->typetv,input_buf)) {
		 param->typetv=(char *)MAlloc((size_t)buflen*sizeof(char),
					      "ilupacksolver");
		 strcpy(param->typetv,input_buf);
	      }
	   }
	   else if (!strcmp("FCpart",fnames[ifield])) {
              if (strcmp(param->FCpart,input_buf)) {
		 param->FCpart=(char *)MAlloc((size_t)buflen*sizeof(char),
					      "ilupacksolver");
		 strcpy(param->FCpart,input_buf);
	      }
	   }
	   else if (!strcmp("solver",fnames[ifield])) {
              if (strcmp(param->solver,input_buf)) {
		 param->solver=(char *)MAlloc((size_t)buflen*sizeof(char),
					      "ilupacksolver");
		 strcpy(param->solver,input_buf);
	      }
	   }
	   else if (!strcmp("ordering",fnames[ifield])) {
              if (strcmp(param->ordering,input_buf)) {
	         param->ordering=(char *)MAlloc((size_t)buflen*sizeof(char),
						"ilupacksolver");
		 strcpy(param->ordering,input_buf);
	      }
	   }
	   else {
	      /* mexPrintf("%s ignored\n",fnames[ifield]);fflush(stdout); */
	   }
	} 
	else {
	   if (!strcmp("elbow",fnames[ifield])) {
	      param->elbow=*mxGetPr(tmp);
	   }
	   else if (!strcmp("lfilS",fnames[ifield])) {
	      param->lfilS=*mxGetPr(tmp);
	   }
	   else if (!strcmp("lfil",fnames[ifield])) {
	      param->lfil=*mxGetPr(tmp);
	   }
	   else if (!strcmp("maxit",fnames[ifield])) {
	      param->maxit=*mxGetPr(tmp);
	   }
	   else if (!strcmp("droptolS",fnames[ifield])) {
	      param->droptolS=*mxGetPr(tmp);
	   }
	   else if (!strcmp("droptol",fnames[ifield])) {
	      param->droptol=*mxGetPr(tmp);
	   }
	   else if (!strcmp("condest",fnames[ifield])) {
	      param->condest=*mxGetPr(tmp);
	   }
	   else if (!strcmp("restol",fnames[ifield])) {
	      param->restol=*mxGetPr(tmp);
	   }
	   else if (!strcmp("npresmoothing",fnames[ifield])) {
	      param->npresmoothing=*mxGetPr(tmp);
	   }
	   else if (!strcmp("npostmoothing",fnames[ifield])) {
	      param->npostsmoothing=*mxGetPr(tmp);
	   }
	   else if (!strcmp("ncoarse",fnames[ifield])) {
	      param->ncoarse=*mxGetPr(tmp);
	   }
	   else if (!strcmp("matching",fnames[ifield])) {
	      param->matching=*mxGetPr(tmp);
	   }
	   else if (!strcmp("nrestart",fnames[ifield])) {
	      param->nrestart=*mxGetPr(tmp);
	   }
	   else if (!strcmp("damping",fnames[ifield])) {
	      param->damping.r=*mxGetPr(tmp);
	      if (mxIsComplex(tmp))
		 param->damping.i=*mxGetPi(tmp);
	      else
		 param->damping.i=0;
	   }
	   else if (!strcmp("mixedprecision",fnames[ifield])) {
	      param->mixedprecision=*mxGetPr(tmp);
	   }
	   else {
	     /* mexPrintf("%s ignored\n",fnames[ifield]);fflush(stdout); */
	   }
	}
    }



    /* copy right hand side `b' */
    b_input = (mxArray *) prhs [3] ;
    /* get size of input matrix A */
    rhs=(doublecomplex*) MAlloc((size_t)A.nr*sizeof(doublecomplex),"ZGNLHPDilupacksolver:rhs");
    pr=mxGetPr(b_input);

    if (!mxIsComplex(b_input)) {
       for (i=0; i<A.nr; i++) {
	   rhs[i].r=pr[i];
	   rhs[i].i=0;
       }
    }
    else {
       pi=mxGetPi(b_input);
       for (i=0; i<A.nr; i++) {
	   rhs[i].r=pr[i];
	   rhs[i].i=pi[i];
       }
    }






    /* copy initial solution `x0' */
    x0_input = (mxArray *) prhs [4] ;
    /* numerical solution */
    sol=(doublecomplex *)MAlloc((size_t)A.nr*sizeof(doublecomplex),"ZGNLHPDilupacksolver:sol");
    pr=mxGetPr(x0_input);
    if (!mxIsComplex(x0_input)) {
       for (i=0; i<A.nr; i++) {
	   sol[i].r=pr[i];
	   sol[i].i=0;
       }
    }
    else {
       pi=mxGetPi(x0_input);
       for (i=0; i<A.nr; i++) {
	  sol[i].r=pr[i];
	  sol[i].i=pi[i];
       }
    }



    ierr=ZGNLHPDAMGsolver(&A, PRE, param, rhs, sol);


    /* Create a struct matrices for output */
    nlhs=2;
    if (j==-1)
       plhs[1] = mxCreateStructMatrix((mwSize)1, (mwSize)1, nfields+1, fnames);
    else
       plhs[1] = mxCreateStructMatrix((mwSize)1, (mwSize)1, nfields, fnames);
    if (plhs[1]==NULL)
       mexErrMsgTxt("Could not create structure mxArray\n");
    options_output=plhs[1];

    /* export data */
    for (ifield = 0; ifield<nfields; ifield++) {
	tmp = mxGetFieldByNumber(options_input,0,ifield);
	classIDflags[ifield] = mxGetClassID(tmp); 

	ndim = mxGetNumberOfDimensions(tmp);
	dims = mxGetDimensions(tmp);

	/* Create string/numeric array */
	if (classIDflags[ifield] == mxCHAR_CLASS) {
	   if (!strcmp("amg",fnames[ifield])) {
	      output_buf = (char *) mxCalloc((size_t)strlen(param->amg)+1, (size_t)sizeof(char));
	      strcpy(output_buf,param->amg);
	      fout = mxCreateString(output_buf);
	   }
	   else if (!strcmp("presmoother",fnames[ifield])) {
	      output_buf = (char *) mxCalloc((size_t)strlen(param->presmoother)+1, (size_t)sizeof(char));
	      strcpy(output_buf,param->presmoother);
	      fout = mxCreateString(output_buf);
	   }
	   else if (!strcmp("postsmoother",fnames[ifield])) {
	      output_buf = (char *) mxCalloc((size_t)strlen(param->postsmoother)+1, (size_t)sizeof(char));
	      strcpy(output_buf,param->postsmoother);
	      fout = mxCreateString(output_buf);
	   }
	   else if (!strcmp("typecoarse",fnames[ifield])) {
	      output_buf = (char *) mxCalloc((size_t)strlen(param->typecoarse)+1, (size_t)sizeof(char));
	      strcpy(output_buf,param->typecoarse);
	      fout = mxCreateString(output_buf);
	   }
	   else if (!strcmp("typetv",fnames[ifield])) {
	      output_buf = (char *) mxCalloc((size_t)strlen(param->typetv)+1, (size_t)sizeof(char));
	      strcpy(output_buf,param->typetv);
	      fout = mxCreateString(output_buf);
	   }
	   else if (!strcmp("FCpart",fnames[ifield])) {
	      output_buf = (char *) mxCalloc((size_t)strlen(param->FCpart)+1, (size_t)sizeof(char));
	      strcpy(output_buf,param->FCpart);
	      fout = mxCreateString(output_buf);
	   }
	   else if (!strcmp("solver",fnames[ifield])) {
	      output_buf = (char *) mxCalloc((size_t)strlen(param->solver)+1, (size_t)sizeof(char));
	      strcpy(output_buf, param->solver);
	      fout = mxCreateString(output_buf);
	   }
	   else if (!strcmp("ordering",fnames[ifield])) {
	      output_buf = (char *) mxCalloc((size_t)strlen(param->ordering)+1, (size_t)sizeof(char));
	      strcpy(output_buf, param->ordering);
	      fout = mxCreateString(output_buf);
	   }
	   else {
	      /* Get the length of the input string. */
	      buflen = (mxGetM(tmp) * mxGetN(tmp)) + 1;

	      /* Allocate memory for input and output strings. */
	      input_buf  = (char *) mxCalloc((size_t)buflen, (size_t)sizeof(char));
	      output_buf = (char *) mxCalloc((size_t)buflen, (size_t)sizeof(char));
	      
	      /* Copy the string data from tmp into a C string 
		 input_buf. */
	      status = mxGetString(tmp, input_buf, buflen);
	      
	      sizebuf = (size_t)buflen*sizeof(char);
	      memcpy(output_buf, input_buf, sizebuf);
	      fout = mxCreateString(output_buf);
	   }
	} 
	else {
	   if (mxGetPi(tmp)==NULL && strcmp("damping",fnames[ifield]))
	      fout = mxCreateNumericArray(ndim, dims, 
					  classIDflags[ifield], mxREAL);
	   else { /* complex case */
	      fout = mxCreateNumericArray(ndim, dims, 
					  classIDflags[ifield], mxCOMPLEX);
	   }
	   pdata = mxGetData(fout);

	   sizebuf = mxGetElementSize(tmp);
	   if (!strcmp("elbow",fnames[ifield])) {
	      dbuf=param->elbow;
	      memcpy(pdata, &dbuf, sizebuf);
	   }
	   else if (!strcmp("lfilS",fnames[ifield])) {
	      dbuf=param->lfilS;
	      memcpy(pdata, &dbuf, sizebuf);
	   }
	   else if (!strcmp("lfil",fnames[ifield])) {
	      dbuf=param->lfil;
	      memcpy(pdata, &dbuf, sizebuf);
	   }
	   else if (!strcmp("maxit",fnames[ifield])) {
	      dbuf=param->maxit;
	      memcpy(pdata, &dbuf, sizebuf);
	   }
	   else if (!strcmp("droptolS",fnames[ifield])) {
	      dbuf=param->droptolS;
	      memcpy(pdata, &dbuf, sizebuf);
	   }
	   else if (!strcmp("droptol",fnames[ifield])) {
	      dbuf=param->droptol;
	      memcpy(pdata, &dbuf, sizebuf);
	   }
	   else if (!strcmp("condest",fnames[ifield])) {
	      dbuf=param->condest;
	      memcpy(pdata, &dbuf, sizebuf);
	   }
	   else if (!strcmp("restol",fnames[ifield])) {
	      dbuf=param->restol;
	      memcpy(pdata, &dbuf, sizebuf);
	   }
	   else if (!strcmp("npresmoothing",fnames[ifield])) {
	      dbuf=param->npresmoothing;
	      memcpy(pdata, &dbuf, sizebuf);
	   }
	   else if (!strcmp("npostmoothing",fnames[ifield])) {
	      dbuf=param->npostsmoothing;
	      memcpy(pdata, &dbuf, sizebuf);
	   }
	   else if (!strcmp("ncoarse",fnames[ifield])) {
	      dbuf=param->ncoarse;
	      memcpy(pdata, &dbuf, sizebuf);
	   }
	   else if (!strcmp("matching",fnames[ifield])) {
	      dbuf=param->matching;
	      memcpy(pdata, &dbuf, sizebuf);
	   }
	   else if (!strcmp("nrestart",fnames[ifield])) {
	      dbuf=param->nrestart;
	      memcpy(pdata, &dbuf, sizebuf);
	   }
	   else if (!strcmp("damping",fnames[ifield])) {
	      pr=mxGetPr(fout);
	      pi=mxGetPi(fout);
	      *pr=param->damping.r;
	      *pi=param->damping.i;
	   }
	   else if (!strcmp("mixedprecision",fnames[ifield])) {
	      dbuf=param->mixedprecision;
	      memcpy(pdata, &dbuf, sizebuf);
	   }
	   else {
	      memcpy(pdata, mxGetData(tmp), sizebuf);
	   }
	}


	/* Set each field in output structure */
	mxSetFieldByNumber(options_output, (mwIndex)0, ifield, fout);
    }

    /* store number of iteration steps */
    if (j==-1)
       ifield=nfields;
    else
       ifield=j;
    fout=mxCreateDoubleMatrix((mwSize)1,(mwSize)1, mxREAL);
    pr=mxGetPr(fout);
    
    *pr=param->ipar[26];
    
    /* set each field in output structure */
    mxSetFieldByNumber(options_output, (mwIndex)0, ifield, fout);      

    mxFree(fnames);
    mxFree(classIDflags);
    /* mexPrintf("options exported\n"); fflush(stdout); */


    plhs[0] = mxCreateDoubleMatrix((mwSize)A.nr, (mwSize)1, mxCOMPLEX);
    x_output=plhs[0];
    pr=mxGetPr(x_output);
    pi=mxGetPi(x_output);
    
    for (i=0; i<A.nr; i++) {
        pr[i]=sol[i].r;
	pi[i]=sol[i].i;
    }



    /* release right hand side */
    free(rhs);

    /* release solution */
    free(sol);

    /* release input matrix */
    free(A.ia);
    free(A.ja);
    free(A.a);
    
    

    switch (ierr) {
    case  0: /* perfect! */
      break;
    case -1: /* too many iteration steps */
      mexPrintf("!!! ILUPACK Warning !!!\n");
      mexPrintf("number of iteration steps exceeded its limit.\nEither increase `options.maxit'\n or recompute ILUPACK preconditioner using a smaller `options.droptol'");
      break;
    case -2: /* weird, should not occur */
      mexErrMsgTxt("not enough workspace provided.");
      plhs[0]=NULL;
      break;
    case -3: /* breakdown */
      mexErrMsgTxt("iterative solver breaks down.\nMost likely you need to recompute ILUPACK preconditioner using a smaller `options.droptol'");
      plhs[0]=NULL;
      break;
    default: /* zero pivot encountered at step number ierr */
      mexPrintf("iterative solver exited with error code %d",ierr);
      mexErrMsgTxt(".");
      plhs[0]=NULL;
      break;
    } /* end switch */
    
    return;
}
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{

    double * R_KTg, * chainsPrior_Kg, * A_KKg, * xi_pseudocounts_KK;
    
    int K, T, B;
    int j, k, t;

    double * hM_KTg, * xi_KKBg, * updated_chainsPrior_Kg, * updated_A_KKg, * divergenceContributions;
    
    /* I will need the logs of chainsPrior_Kg, A_KKg, but the log of A_KKg 
       is the only one for which I'd say computations by memorizing the results.
     */
    double * log_chainsPrior_Kg, * log_A_KKg;
    double * rownormalized_xi_KKBg;
    
    
    double * outputToolPtr;
    int trplarr_ndim = 3;
    int * trplarr_dims = mxMalloc(trplarr_ndim*sizeof(int));
    
    double logeps;
    
    if ( !(3<=nrhs && nrhs<=4) || !(1<=nlhs && nlhs<=5))
        mexErrMsgTxt("hmmmix_frugal_hM_KTg_MatlabC requires 3-4 inputs and 1-5 outputs");

    R_KTg = mxGetPr(prhs[0]);
    chainsPrior_Kg = mxGetPr(prhs[1]);
    A_KKg = mxGetPr(prhs[2]);

    
    K = mxGetM(prhs[0]);
    T = mxGetN(prhs[0]);
    
    /* I decided to define B=T-1 because a needed a single letter name for
     * that quantity T-1. I thought naming xi_KKTg when it actually had T-1
     * elements in the last dimension was more confusing than naming it
     * xi_KKBg. I'm not sure if this is a good call.
     */
    B = T-1;
    assert(mxGetM(prhs[1])*mxGetN(prhs[1]) == K);
    assert(mxGetM(prhs[2]) == K);
    assert(mxGetN(prhs[2]) == K);
    
    /* We're going to be using this value to make sure that the zeros in
     * the transition matrices correspond logs whose values are very small
     * compared the the loglikelihoods that we're dealing with in R_KTg.
     */
    logeps = T*vectorMinimum(R_KTg, K*T);
    if (logeps > 0)
        logeps = -T;
    
    /* Our implementation of fwd_back works with logs so we need to make
     * the conversions somewhere. It's a bit stupid to do it in C instead
     * of doing in Matlab with a wrapper, though.
     */
    
    log_A_KKg = mxMalloc(K*K*sizeof(double));
    for (k=0;k<K*K;++k) {
        if (A_KKg[k] < 0) {
            mexPrintf("Found a value < 0 in a transition matrix.\n");
            for (k=0;k<K*K;++k)
                mexPrintf("A_KKg[%d]=%f.\n", k, A_KKg[k]);
            mexErrMsgTxt("transition matrix fault");
        } else if (A_KKg[k] == 0)
            log_A_KKg[k] = logeps;
        else
            log_A_KKg[k] = log(A_KKg[k]);
    }

    log_chainsPrior_Kg = mxMalloc(K*sizeof(double));
    for (k=0;k<K;++k) {
        if (chainsPrior_Kg[k] < 0) {
            mexPrintf("Found a value < 0 in a the initial state priors.\n");
            for (k=0;k<K*K;++k)
                mexPrintf("chainsPrior_Kg[%d]=%f.\n", k, chainsPrior_Kg[k]);
            mexErrMsgTxt("initial state prior fault");
        } else if (chainsPrior_Kg[k] == 0)
            log_chainsPrior_Kg[k] = logeps;
        else
            log_chainsPrior_Kg[k] = log(chainsPrior_Kg[k]);
    }
    
    /* If no pseudocounts were supplied, we fill up the values with zeros. */
    if (4<=nrhs)
        xi_pseudocounts_KK = mxGetPr(prhs[3]);
    else {
        xi_pseudocounts_KK = mxMalloc(K*K*sizeof(double));
        for (k=0; k<K*K; ++k)
            xi_pseudocounts_KK[k] = 0;
    }
    

    /*  assign the memory for the variables in which we'll construct
        the arrays of values that we want to output
     */
    hM_KTg = mxMalloc(K*T*sizeof(double));
    xi_KKBg = mxMalloc(K*K*B*sizeof(double));
    updated_chainsPrior_Kg = mxMalloc(K*sizeof(double));
    updated_A_KKg = mxMalloc(K*K*sizeof(double));

    /* DEBUGGING
    for(k=0;k<K;++k)
        mexPrintf("log_chainsPrior_Kg[%d]=%f\n", k,log_chainsPrior_Kg[k]);
    for(k=0;k<K*K;++k)
        mexPrintf("log_A_KKg[%d]=%f\n", k,log_A_KKg[k]);
    */

    /* Drowned in all the code, this is the line that makes the call to the
     * fwd_back code that does the work.
     */
    
    fwd_back(hM_KTg, xi_KKBg, log_chainsPrior_Kg, log_A_KKg, 0, R_KTg, K, T, 1);
    /* The C function spits out values in log form so we have to exponentiate
     * and then normalize them. We could have used intermediary variables, but
     * this is C so we're being greedy with memory.
     */
    
    for(k=0;k<K*T;++k)
        hM_KTg[k] = exp(hM_KTg[k]);
    normalizeColumns(hM_KTg, K, T, 0);
    for(k=0;k<K*K*B;++k)
        xi_KKBg[k] = exp(xi_KKBg[k]);
    normalizeColumns(xi_KKBg, K*K, B, 0);
    
    
    
    /* find the MLE for A_KKg using the twoslice marginals in xi_KKBg */
    if (nlhs >= 2) {
        /* the T-1 is because the last values are junk */
        transition_matrix_MLE_from_twoslice_marginals_pseudocounts_normalized(updated_A_KKg, xi_KKBg, K, T-1, xi_pseudocounts_KK);
    }

    /* It's a bit pointless to have another variable for that, but I'm not
     *  completely sure right now if the "pi" vector for HMM corresponds to
     *  the first filtered states or it's not that at all.
     */
    for (k=0;k<K;++k)
        updated_chainsPrior_Kg[k] = hM_KTg[k];
    
    /* Now comes the divergence contributions, the complicated part.
     * I'll return 3 values. The first term without the "S" factor in front,
     * the hM log(hM) entropy and then the result of
     *      S*(first term) - (second term)
     */
    if (nlhs >= 5) {
        
        /* initialization */
        
        divergenceContributions = mxMalloc(2*sizeof(double));
        
        rownormalized_xi_KKBg = mxMalloc(K*K*B*sizeof(double));
        memcpy(rownormalized_xi_KKBg, xi_KKBg, K*K*B*sizeof(double));
        for (t=0; t<T-1; ++t)
            normalizeRows(rownormalized_xi_KKBg + K*K*t, K, K, 1e-16);
        
        divergenceContributions[0] = 0;
        divergenceContributions[1] = 0;

        
        /* on R_KTg */
        for (t=0;t<T;++t) {
            for (k=0; k<K; ++k) {
                divergenceContributions[0] += hM_KTg[k+K*t] * R_KTg[k+K*t];
            }
        }
        
        /* log f(M|A,pi) */
        for (k=0;k<K;++k) {
            divergenceContributions[0] += hM_KTg[k + K*0] * log_chainsPrior_Kg[k];
            divergenceContributions[1] += hM_KTg[k + K*0] * log(hM_KTg[k + K*0] + 1e-16);
        }
            
        for (t=0;t<T-1;++t) {
            for (k=0; k<K; ++k) {
                for (j=0; j<K; ++j) {
                    /* newer, maybe right ? */
                    divergenceContributions[0] += hM_KTg[k + K*t] * rownormalized_xi_KKBg[k+K*j+K*K*t] * log_A_KKg[k+K*j];
                    divergenceContributions[1] += hM_KTg[k + K*t] * rownormalized_xi_KKBg[k+K*j+K*K*t] * log(rownormalized_xi_KKBg[k+K*j+K*K*t] + 1e-16);
                    
                    /* older, probably wrong
                    divergenceContributions[0] += xi_KKTg[k+K*j+K*K*t] * log_A_KKg[k+K*j];
                    divergenceContributions[1] += xi_KKTg[k+K*j+K*K*t] * log(rownormalized_xi_KKTg[k+K*j+K*K*t] + 1e-16);
                     */
                }
            }
        }

        /* the pseudocounts. Don't forget to call the function 
         * hmmmix_pseudoCounts_logNormalizingConstant(A,pseudoCounts)
         * in Matlab after to get the correct divergence term.
         */
        for (k=0; k<K; ++k) {
            for (j=0; j<K; ++j) {
                divergenceContributions[0] += xi_pseudocounts_KK[k+K*j] * log_A_KKg[k+K*j];
            }
        }
        
    }
    
    
    /* output to Matlab */
    
    if (nlhs >= 1) {
        plhs[0] = mxCreateDoubleMatrix(K,T,mxREAL);
        outputToolPtr = mxGetPr(plhs[0]);
        memcpy(outputToolPtr, hM_KTg, K*T*sizeof(double));
    }

    if (nlhs >= 2) {
        trplarr_dims[0] = K;
        trplarr_dims[1] = K;
        trplarr_dims[2] = T-1;
        
        plhs[1] = mxCreateNumericArray(trplarr_ndim, trplarr_dims, mxDOUBLE_CLASS, mxREAL);
        outputToolPtr = mxGetPr(plhs[1]);
        memcpy(outputToolPtr, xi_KKBg, K*K*B*sizeof(double));
    }

    if (nlhs >= 3) {
        plhs[2] = mxCreateDoubleMatrix(K,1,mxREAL);
        outputToolPtr = mxGetPr(plhs[2]);
        memcpy(outputToolPtr, updated_chainsPrior_Kg, K*sizeof(double));
    }

    if (nlhs >= 4) {
        plhs[3] = mxCreateDoubleMatrix(K,K,mxREAL);
        outputToolPtr = mxGetPr(plhs[3]);
        memcpy(outputToolPtr, updated_A_KKg, K*K*sizeof(double));
    }
    
    if (nlhs >= 5) {
        plhs[4] = mxCreateDoubleMatrix(2,1,mxREAL);
        outputToolPtr = mxGetPr(plhs[4]);
        memcpy(outputToolPtr, divergenceContributions, 2*sizeof(double));
    }
    
    /* cleaning up */
    
    mxFree(trplarr_dims);
    mxFree(hM_KTg);  mxFree(xi_KKBg);
    mxFree(updated_A_KKg);  mxFree(updated_chainsPrior_Kg);
    mxFree(log_A_KKg); mxFree(log_chainsPrior_Kg);
    
    /* because we allocate xi_pseudocounts_KK when (4<=nrhs) fails */
    if (4>nrhs)
        mxFree(xi_pseudocounts_KK);

        
    if (nlhs >= 5) {
        mxFree(divergenceContributions);
        mxFree(rownormalized_xi_KKBg);
    }
    
        
    return;
}
Example #24
0
void mexFunction(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
{

    //mexPrintf("test A\n");
    //   Check the number of inputs/outputs
    if (nlhs == 0)
        nlhs = 1;
    if (nrhs != 1)
        mexErrMsgTxt("Incorrect number of inputs");
    else if (nlhs > 2)
        mexErrMsgTxt("Too many outputs.");

    // mexPrintf("test A.2\n");
    //    Setup the set inputs
    //N
    int input_N = (int)(mcwrap_size(prhs[1 - 1], 2));

    //mexPrintf("test B\n");
    //    Setup the inputs
    //samples
    //Check that we have the correct dimensions!
    {
        int numdims = mxGetNumberOfDimensions(prhs[1 - 1]);
        if (numdims != 2) {
            mexErrMsgTxt("Incorrect number of dimensions in input: samples");
        }
        const mwSize* dims2 = mxGetDimensions(prhs[1 - 1]);
        int dims[] = { 1, input_N };
        for (long ii = 0; ii < numdims; ii++) {
            if (dims[ii] != dims2[ii]) {
                mexErrMsgTxt("Incorrect size of input: samples");
            }
        }
    }
    double* input_samples = mxGetPr(prhs[1 - 1]);

    //mexPrintf("test C\n");
    //    Setup the outputs
    //dipscore
    double* output_dipscore;
    if (1 <= nlhs) {
        if ((2 < 1) || (2 > 20)) {
            mexErrMsgTxt("Bad number of dimensions for my taste: 2");
        }
        {
            int dims2[] = { 1, 1 };
            for (long ii = 0; ii < 2; ii++) {
                if ((dims2[ii] < 1) || (dims2[ii] > 10000000000.0)) {
                    mexErrMsgTxt("Bad array size for my taste: 1,1");
                }
            }
        }

        mwSize dims[] = { 1, 1 };
        plhs[1 - 1] = mxCreateNumericArray(2, dims, mxDOUBLE_CLASS, mxREAL);
        output_dipscore = mxGetPr(plhs[1 - 1]);
    }
    //cutpoint
    double* output_cutpoint;
    if (2 <= nlhs) {
        if ((2 < 1) || (2 > 20)) {
            mexErrMsgTxt("Bad number of dimensions for my taste: 2");
        }
        {
            int dims2[] = { 1, 1 };
            for (long ii = 0; ii < 2; ii++) {
                if ((dims2[ii] < 1) || (dims2[ii] > 10000000000.0)) {
                    mexErrMsgTxt("Bad array size for my taste: 1,1");
                }
            }
        }

        mwSize dims[] = { 1, 1 };
        plhs[2 - 1] = mxCreateNumericArray(2, dims, mxDOUBLE_CLASS, mxREAL);
        output_cutpoint = mxGetPr(plhs[2 - 1]);
    }

    //mexPrintf("test D\n");
    //    Run the subroutine
    isocut5_mex(
        output_dipscore,
        output_cutpoint,
        input_N,
        input_samples

        );

    //mexPrintf("test E\n");
    //    Free the inputs
    //samples

    //mexPrintf("test F\n");
    //    Set the outputs
    //dipscore
    //cutpoint

    //mexPrintf("test G\n");

    /**** We are done *******/
}
Example #25
0
void mexFunction(int             nlhs,      /* No. of output arguments */
                 mxArray         *plhs[],   /* Output arguments. */ 
                 int             nrhs,      /* No. of input arguments. */
                 const mxArray   *prhs[])   /* Input arguments. */
{
   int            i=0;
   int            ndim=0, lima_ndim=0;
   int            nc=0, nr=0, ni=0;
   const int      *cdim=NULL, *lima_cdim=NULL;
   unsigned int   dim[3];
   int            *nn=NULL;
   int            *rs=NULL;
   int            *rw=NULL;
   int            *lima=NULL;
   double         *pp=NULL;
   double         *pm=NULL;
   double         *d_tmp=NULL;
   double         *opm=NULL;

   if (nrhs == 0) mexErrMsgTxt("usage: pm = pm_merge_regions(pm,lima,i,j,n,p,rs)");
   if (nrhs != 7) mexErrMsgTxt("pm_merge_regions: 7 input arguments required");
   /*
   if (nlhs != 1) mexErrMsgTxt("pm_merge_regions: 1 output argument required");
   */

   /* Get phase map. */

   if (!mxIsNumeric(prhs[0]) || mxIsComplex(prhs[0]) || mxIsSparse(prhs[0]) || !mxIsDouble(prhs[0]))
   {
      mexErrMsgTxt("pm_merge_regions: pm must be numeric, real, full and double");
   }
   ndim = mxGetNumberOfDimensions(prhs[0]);
   if ((ndim < 2) | (ndim > 3))
   {
      mexErrMsgTxt("pm_merge_regions: pm must be 2 or 3-dimensional");
   }
   cdim = mxGetDimensions(prhs[0]);
   pm = mxGetPr(prhs[0]);

   /* Get image of labels. */

   if (!mxIsNumeric(prhs[1]) || mxIsComplex(prhs[1]) || mxIsSparse(prhs[1]) || !mxIsDouble(prhs[1]))
   {
      mexErrMsgTxt("pm_merge_regions: lima must be numeric, real, full and double");
   }
   lima_ndim = mxGetNumberOfDimensions(prhs[1]);
   if (lima_ndim != ndim)
   {
      mexErrMsgTxt("pm_merge_regions: pm and lima must have same dimensionality");
   }
   lima_cdim = mxGetDimensions(prhs[1]);
   for (i=0; i<ndim; i++)
   {
      if (cdim[i] != lima_cdim[i])
      {
         mexErrMsgTxt("pm_merge_regions: pm and lima must have same size");
      }
   }
   d_tmp = mxGetPr(prhs[1]);

   /* Fix dimensions to allow for 2D and 3D data. */

   dim[0]=cdim[0]; dim[1]=cdim[1];
   if (ndim==2) {dim[2]=1; ndim=3;} else {dim[2]=cdim[2];} 
   for (i=0, ni=1; i<ndim; i++)
   {
      ni *= dim[i];
   }

   /* Convert double representation of lima into int's. */

   lima = (int *) mxCalloc(ni,sizeof(int));
   for (i=0; i<ni; i++) {lima[i] = ((int) (d_tmp[i]+0.1));} 

   /* Get vector of row indicies into connectogram matrix */

   if (!mxIsNumeric(prhs[2]) || mxIsComplex(prhs[2]) || mxIsSparse(prhs[2]) || !mxIsDouble(prhs[2]))
   {
      mexErrMsgTxt("pm_merge_regions: i must be numeric, real, full and double");
   }
   nc = mxGetM(prhs[2]);
   d_tmp = mxGetPr(prhs[2]);
   if (mxGetN(prhs[2]) != 1)
   {
      mexErrMsgTxt("pm_merge_regions: i must be a column matrix");
   }
   ii = (int *) mxCalloc(nc,sizeof(int));
   for (i=0; i<nc; i++) {ii[i] = ((int) (d_tmp[i]+0.1));}

   /* Get vector of column indicies into connectogram matrix */

   if (!mxIsNumeric(prhs[3]) || mxIsComplex(prhs[3]) || mxIsSparse(prhs[3]) || !mxIsDouble(prhs[3]))
   {
      mexErrMsgTxt("pm_merge_regions: j must be numeric, real, full and double");
   }
   if (mxGetM(prhs[3]) != nc || mxGetN(prhs[3]) != 1)
   {
      mexErrMsgTxt("pm_merge_regions: j must be a column matrix of same size as i");
   }
   d_tmp = mxGetPr(prhs[3]);
   jj = (int *) mxCalloc(nc,sizeof(int));
   for (i=0; i<nc; i++) {jj[i] = ((int) (d_tmp[i]+0.1));}

   /* Get entrys for first connectogram matrix (containing border sizes). */

   if (!mxIsNumeric(prhs[4]) || mxIsComplex(prhs[4]) || mxIsSparse(prhs[4]) || !mxIsDouble(prhs[4]))
   {
      mexErrMsgTxt("pm_merge_regions: n must be numeric, real, full and double");
   }
   if (mxGetM(prhs[4]) != nc || mxGetN(prhs[4]) != 1)
   {
      mexErrMsgTxt("pm_merge_regions: n must be a column matrix of same size as i");
   }
   d_tmp = mxGetPr(prhs[4]);
   nn = (int *) mxCalloc(nc,sizeof(int));
   for (i=0; i<nc; i++) {nn[i] = ((int) (d_tmp[i]+0.1));}

   /* Get entrys for second connectogram matrix (containing phase differences along borders). */

   if (!mxIsNumeric(prhs[5]) || mxIsComplex(prhs[5]) || mxIsSparse(prhs[5]) || !mxIsDouble(prhs[5]))
   {
      mexErrMsgTxt("pm_merge_regions: p must be numeric, real, full and double");
   }
   if (mxGetM(prhs[5]) != nc || mxGetN(prhs[5]) != 1)
   {
      mexErrMsgTxt("pm_merge_regions: p must be a column matrix of same size as i");
   }
   d_tmp = mxGetPr(prhs[5]);
   pp = (double *) mxCalloc(nc,sizeof(double)); /* Use local copy to avoid side effects. */
   memcpy(pp,d_tmp,nc*sizeof(double));   

   /* Get vector of region sizes (in voxels) */

   if (!mxIsNumeric(prhs[6]) || mxIsComplex(prhs[6]) || mxIsSparse(prhs[6]) || !mxIsDouble(prhs[6]))
   {
      mexErrMsgTxt("pm_merge_regions: rs must be numeric, real, full and double");
   }
   nr = mxGetM(prhs[6]);
   d_tmp = mxGetPr(prhs[6]);
   if (mxGetN(prhs[6]) != 1)
   {
      mexErrMsgTxt("pm_merge_regions: rs must be a column matrix");
   }
   rs = (int *) mxCalloc(nr,sizeof(int));
   for (i=0; i<nr; i++) {rs[i] = ((int) (d_tmp[i]+0.1));}
   
   /* Allocate mem for unwrapped output phasemap. */

      plhs[0] = mxCreateNumericArray(mxGetNumberOfDimensions(prhs[0]),
                                  mxGetDimensions(prhs[0]),mxDOUBLE_CLASS,mxREAL);
   opm = mxGetPr(plhs[0]);
   
   rw = (int *) mxCalloc(nr,sizeof(int));

   merge_regions(nn,pp,nc,rs,nr,rw);

   for (i=0; i<ni; i++)
   {
      if (lima[i]) {opm[i] = pm[i] + 2.0*PI*rw[lima[i]-1];}
      else {opm[i] = pm[i];}
   }

   mxFree(lima);     
   mxFree(ii);     
   mxFree(jj);     
   mxFree(nn);
   mxFree(pp);     
   mxFree(rs);     

   return;
}
Example #26
0
static mxArray *makeMxFromNumeric(const PyArrayObject *pSrc)
{
  npy_intp lRows=0, lCols=0;
  bool lIsComplex;
  bool lIsNotAMatrix = false;
  double *lR = NULL;
  double *lI = NULL;
  mxArray *lRetval = NULL;
  mwSize dims[NPY_MAXDIMS];
  mwSize nDims = pSrc->nd;
  const PyArrayObject *ap=NULL;

  switch (pSrc->nd) {
  case 0:                       // XXX the evil 0D
    lRows = 1;
    lCols = 1;
    lIsNotAMatrix = true;
    break;
  case 1:
    lRows = pSrc->dimensions[0];
    lCols = min(1, lRows); // for array([]): to avoid zeros((0,1)) !
    lIsNotAMatrix = true;
    break;
  default:
      for (mwSize i = 0;i != nDims; i++) {
        dims[i]=(mwSize)pSrc->dimensions[i];
      }
    break;
  }
  switch (pSrc->descr->type_num) {
  case PyArray_OBJECT:
    PyErr_SetString(PyExc_TypeError, "Non-numeric array types not supported");
    return NULL;
  case PyArray_CFLOAT:
  case PyArray_CDOUBLE:
    lIsComplex = true;
    break;
  default:
    lIsComplex = false;
  }

  // converts to fortran order if not already
  if(!PyArray_ISFORTRAN(pSrc)){ 
    ap = (PyArrayObject * const)PyArray_FromArray((PyArrayObject*)pSrc,NULL,NPY_ALIGNED|NPY_F_CONTIGUOUS);
  }
  else{
    ap = pSrc;
  }

  if(lIsNotAMatrix)
    lRetval = mxCreateDoubleMatrix(lRows, lCols, lIsComplex ? mxCOMPLEX : mxREAL);
  else
    lRetval = mxCreateNumericArray(nDims,dims,mxDOUBLE_CLASS,lIsComplex ? mxCOMPLEX : mxREAL);

  if (lRetval == NULL) return NULL;
  lR = mxGetPr(lRetval);
  lI = mxGetPi(lRetval);
  if (lIsNotAMatrix) {
    void *p = PyArray_DATA(ap);
    switch (ap->descr->type_num) {
    case PyArray_CHAR:
      copyNumericVector2Mx((char *)(p), lRows, lR, pSrc->strides);
      break;

    case PyArray_UBYTE:
      copyNumericVector2Mx((unsigned char *)(p), lRows, lR, pSrc->strides);
      break;

    case PyArray_SBYTE:
      copyNumericVector2Mx((signed char *)(p), lRows, lR, pSrc->strides);
      break;

    case PyArray_SHORT:
      copyNumericVector2Mx((short *)(p), lRows, lR, pSrc->strides);
      break;

    case PyArray_INT:
      copyNumericVector2Mx((int *)(p), lRows, lR, pSrc->strides);
      break;

    case PyArray_LONG:
      copyNumericVector2Mx((long *)(p), lRows, lR, pSrc->strides);
      break;

    case PyArray_FLOAT:
      copyNumericVector2Mx((float *)(p), lRows, lR, pSrc->strides);
      break;

    case PyArray_DOUBLE:
      copyNumericVector2Mx((double *)(p), lRows, lR, pSrc->strides);
      break;

    case PyArray_CFLOAT:
      copyCplxNumericVector2Mx((float *)(p), lRows, lR, lI, pSrc->strides);
      break;

    case PyArray_CDOUBLE:
      copyCplxNumericVector2Mx((double *)(p), lRows, lR, lI, pSrc->strides);
      break;
    }
  } else {
    void *p = PyArray_DATA(ap);
    npy_intp size = PyArray_SIZE(pSrc);

    switch (pSrc->descr->type_num) {
    case PyArray_CHAR:
      copyNumeric2Mx((char *)p,size,lR);
      break;

    case PyArray_UBYTE:
      copyNumeric2Mx((unsigned char *)p,size,lR);
      break;

    case PyArray_SBYTE:
      copyNumeric2Mx((signed char *)p,size,lR);
      break;

    case PyArray_SHORT:
      copyNumeric2Mx((short *)p,size,lR);
      break;

    case PyArray_INT:
      copyNumeric2Mx((int *)p,size,lR);
      break;

    case PyArray_LONG:
      copyNumeric2Mx((long *)p,size,lR);
      break;

    case PyArray_FLOAT:
      copyNumeric2Mx((float *)p,size,lR);
      break;

    case PyArray_DOUBLE:
      copyNumeric2Mx((double *)p,size,lR);
      break;

    case PyArray_CFLOAT:
      copyCplxNumeric2Mx((float *)p,size,lR,lI);
      break;

    case PyArray_CDOUBLE:
      copyCplxNumeric2Mx((double *)p,size,lR,lI);
      break;
    }
  }
  
  if(ap != pSrc){
    Py_DECREF(const_cast<PyArrayObject *>(ap));
  }
  return lRetval;
}
//=================================================================================
//  mexFunction
//
//  Main entry function
//
//  Takes as input
//  - an image stack (color or grayscale) and
//  - the number of supervoxels requried
//
//  Generates output:
//  - supervoxel label volume (same indexing order as input stack)
//  - number of generated supervoxels (which could differ from the input number)
//=================================================================================
void mexFunction(int nlhs, mxArray *plhs[],
                 int nrhs, const mxArray *prhs[])
{
    if (nrhs < 1) {
        mexErrMsgTxt("At least one argument is required.") ;
    } else if(nrhs > 3) {
        mexErrMsgTxt("Too many input arguments.");
    }
    if(nlhs!=2) {
        mexErrMsgIdAndTxt("SLIC:nlhs","Two outputs required, a labels and the number of labels, i.e supervoxels.");
    }
    //---------------------------
    // Variable declarations
    //---------------------------
    int numReqdSupervoxels = 200;//default value
    double compactness = 10;//default value
    int width;
    int height;
    int depth;
    int colors;
    int sz2;
    int sz3;
    int sz4;
    int i, ii;
    int x, y, z;
    unsigned char* rin; unsigned char* gin; unsigned char* bin;
    int* klabels;
    int* clabels;
    double* lvec; double* avec; double* bvec;
    int step;
    int* seedIndices;
    int numseeds;
    double* kseedsx;double* kseedsy;double* kseedsz;
    double* kseedsl;double* kseedsa;double* kseedsb;
    int k;
    const mwSize* dims;//int* dims;
    int* outputNumSuperpixels;
    int* outlabels;
    int finalNumberOfLabels;
    unsigned char* imgbytes;
    int testcount;
    //---------------------------
    size_t numelements   = mxGetNumberOfElements(prhs[0]) ;// returns number of bytes
    mwSize numdims = mxGetNumberOfDimensions(prhs[0]) ;
    dims  = mxGetDimensions(prhs[0]) ;
    imgbytes  = (unsigned char*)mxGetData(prhs[0]) ;//mxGetData returns a void pointer, so cast it
    if(3 == numdims)
    {
        depth = dims[2];
        width = dims[1];
        height = dims[0];
    }
    else if(4 == numdims)
    {
        depth = dims[3];
        colors = dims[2];
        width = dims[1];
        height = dims[0];
    }
    else return;
    
    sz2 = width*height;
    sz3 = width*height*depth;
    sz4 = width*height*depth*colors;
    //---------------------------
    numReqdSupervoxels  = mxGetScalar(prhs[1]);
    compactness         = mxGetScalar(prhs[2]);
    
    //---------------------------
    // Allocate memory
    //---------------------------
    rin     = mxMalloc( sizeof(unsigned char)   * sz3 ) ;
    gin     = mxMalloc( sizeof(unsigned char)   * sz3 ) ;
    bin     = mxMalloc( sizeof(unsigned char)   * sz3 ) ;
    lvec    = mxMalloc( sizeof(double)          * sz3 ) ;
    avec    = mxMalloc( sizeof(double)          * sz3 ) ;
    bvec    = mxMalloc( sizeof(double)          * sz3 ) ;
    klabels = mxMalloc( sizeof(int)             * sz3 );//original k-means labels
    clabels = mxMalloc( sizeof(int)             * sz3 );//corrected labels after enforcing connectivity
    seedIndices = mxMalloc( sizeof(int)         * sz3 );

    //---------------------------
    // Perform color conversion
    //---------------------------
    //if(2 == numdims)
    if(numelements/sz3 == 1)//if it is a grayscale image, copy the values directly into the lab vectors
    {
        for(z = 0, ii = 0; z < depth; z++)
        {
            for(x = 0; x < width; x++)//reading data from column-major MATLAB matrics to row-major C matrices (i.e perform transpose)
            {
                for(y = 0; y < height; y++)
                {
                    i = z*sz2 + y*width+x;
                    lvec[i] = avec[i] = bvec[i] = imgbytes[ii];
                    ii++;
                }
            }
        }
    }
    else//else covert from rgb to lab
    {
        for(z = 0; z < depth; z++)
        {
            ii = z*sz2*3;
            for(x = 0; x < width; x++)//reading data from column-major MATLAB matrics to row-major C matrices (i.e perform transpose)
            {
                for(y = 0; y < height; y++)
                {
                    i = z*sz2 + y*width + x;
                    rin[i] = imgbytes[ii];
                    gin[i] = imgbytes[ii+sz2];
                    bin[i] = imgbytes[ii+sz2+sz2];
                    ii++;
                }
            }
        }
    
        rgbtolab(rin,gin,bin,sz3,lvec,avec,bvec);
    }
    
    //---------------------------
    // Find seeds
    //---------------------------
    step = pow((double)(sz3)/(double)(numReqdSupervoxels), 1.0/3.0) + 0.5;//step size is the cube-root of the average area of a supervoxel
    getLABXYZSeeds(width,height,depth,numReqdSupervoxels,step,seedIndices,&numseeds);
    
    kseedsx    = mxMalloc( sizeof(double)      * numseeds ) ;
    kseedsy    = mxMalloc( sizeof(double)      * numseeds ) ;
    kseedsz    = mxMalloc( sizeof(double)      * numseeds ) ;
    kseedsl    = mxMalloc( sizeof(double)      * numseeds ) ;
    kseedsa    = mxMalloc( sizeof(double)      * numseeds ) ;
    kseedsb    = mxMalloc( sizeof(double)      * numseeds ) ;
    testcount = 0;
    for(k = 0; k < numseeds; k++)
    {
        if(seedIndices[k] >= 0)
        {
            kseedsz[k] = (int)(seedIndices[k]/sz2);
            kseedsy[k] = (int)((seedIndices[k]-kseedsz[k]*sz2)/width);
            kseedsx[k] = (int)(seedIndices[k]-kseedsz[k]*sz2)%width;
            //kseedsx[k] = (int)(seedIndices[k]-kseedsz[k]*sz2-kseedsy[k]*width);
            kseedsl[k] = lvec[seedIndices[k]];
            kseedsa[k] = avec[seedIndices[k]];
            kseedsb[k] = bvec[seedIndices[k]];
            testcount++;
        }
    }
    //---------------------------
    // Compute superpixels
    //---------------------------
    PerformSupervoxelSLIC(lvec, avec, bvec, kseedsl,kseedsa,kseedsb,kseedsx,kseedsy,kseedsz,width,height,depth,numseeds,klabels,step,compactness);
    //---------------------------
    // Enforce connectivity
    //---------------------------
    EnforceSupervoxelConnectivity(klabels,width,height,depth,numReqdSupervoxels,clabels,&finalNumberOfLabels);
    //---------------------------
    // Assign output labels
    //---------------------------
    //plhs[0] = mxCreateNumericMatrix(height,width,mxINT32_CLASS,mxREAL);
    mwSize ndims[3]; ndims[0] = height; ndims[1] = width; ndims[2] = depth;
    plhs[0] = mxCreateNumericArray(3,ndims,mxINT32_CLASS,mxREAL);
    outlabels = mxGetData(plhs[0]);
    
    for(z = 0, ii = 0; z < depth; z++)
    {
        for(x = 0; x < width; x++)//copying data from row-major C matrix to column-major MATLAB matrix (i.e. perform transpose)
        {
            for(y = 0; y < height; y++)
            {
                i = z*sz2 + y*width + x;
                outlabels[ii] = clabels[i];
                ii++;
            }
        }
    }
    //---------------------------
    // Assign number of labels/seeds
    //---------------------------
    plhs[1] = mxCreateNumericMatrix(1,1,mxINT32_CLASS,mxREAL);
    outputNumSuperpixels = (int*)mxGetData(plhs[1]);//gives a void*, cast it to int*
    *outputNumSuperpixels = finalNumberOfLabels;
    //---------------------------
    // Deallocate memory
    //---------------------------
    mxFree(kseedsx);
    mxFree(kseedsy);
    mxFree(kseedsz);
    mxFree(kseedsl);
    mxFree(kseedsa);
    mxFree(kseedsb);

    mxFree(rin);
    mxFree(gin);
    mxFree(bin);
    mxFree(lvec);
    mxFree(avec);
    mxFree(bvec);
    mxFree(klabels);
    mxFree(clabels);
    mxFree(seedIndices);
}
Example #28
0
void mexFunction(
    int		  nout, 	/* number of expected outputs */
    mxArray	  *out[],	/* mxArray output pointer array */
    int		  nin, 		/* number of inputs */
    const mxArray	  *in[]	/* mxArray input pointer array */
    )
{
   
  enum {IN_CLASS=0,IN_UNARY,IN_PAIRWISE,IN_LABELCOST,IN_EXPANSION} ;
  enum {OUT_LABELS=0, OUT_ENERGY, OUT_ENERGYAFTER} ;

  bool expansion = false;  

  /****************************************************************************
   * ERROR CHECKING
   ***************************************************************************/
  expansion = *mxGetPr(in[IN_EXPANSION]) > 0;
  if (nout > 3)
    mexErrMsgTxt("At most three outputs are allowed.");

  if(mxGetClassID(in[IN_CLASS]) != mxDOUBLE_CLASS)
    mexErrMsgTxt("Class must be a vector of class DOUBLE");
  if(mxGetM(in[IN_CLASS]) != 1 && mxGetN(in[IN_CLASS]) != 1)
    mexErrMsgTxt("Class must be a vector");

  if(mxGetClassID(in[IN_LABELCOST]) != mxSINGLE_CLASS)
    mexErrMsgTxt("Labelcost term must be a matrix of class SINGLE");

  int num_labels = mxGetM(in[IN_UNARY]);
  int num_pixels = mxGetN(in[IN_UNARY]);
  
  if(mxGetM(in[IN_CLASS]) != num_pixels && mxGetN(in[IN_CLASS]) != num_pixels)
    mexErrMsgTxt("Class size does not match cols in Unary term.");
  if(mxGetM(in[IN_LABELCOST]) != mxGetN(in[IN_LABELCOST]) || 
     mxGetM(in[IN_LABELCOST]) != num_labels)
    mexErrMsgTxt("Labelcost is not symmetric or does not match rows in Unary term.");

  if(mxGetM(in[IN_PAIRWISE]) != num_pixels || 
     mxGetN(in[IN_PAIRWISE]) != num_pixels)
    mexErrMsgTxt("Pairwise is not symmetric or does not match cols in Unary term.");


  /* Create output arrays */
  mwSize dims[2] = {1,0};
  out[OUT_ENERGY] = mxCreateNumericArray(1, dims, mxDOUBLE_CLASS, mxREAL);
  out[OUT_ENERGYAFTER] = mxCreateNumericArray(1, dims, mxDOUBLE_CLASS, mxREAL);
  double * energy = mxGetPr(out[OUT_ENERGY]);
  double * energy_after = mxGetPr(out[OUT_ENERGYAFTER]);

  mwSize pdims[2] = {num_pixels,1};
  out[OUT_LABELS] = mxCreateNumericArray(1,pdims,mxDOUBLE_CLASS, mxREAL);
  double * labels = mxGetPr(out[OUT_LABELS]);

  /* Data costs are nlabels rows x npixels cols */
  double * data = (double *)mxGetData(in[IN_UNARY]);
  double * classes = mxGetPr(in[IN_CLASS]);

  if (num_pixels == 1) { /* one pixel is a special case */
    *energy = data[(int)classes[0]];
    int minlabel = (int)classes[0];
    double mincost  = *energy;
    for(int i = 0; i < num_labels; i++)
      if(data[i] < mincost) {
        mincost = data[i];
        minlabel = i;
      }
    labels[0] = minlabel;
    *energy_after = mincost;
    return;
  }

  /****************************************************************************
   * Setup Graph and Perform Optimization
   ***************************************************************************/
  try {
    GCoptimizationGeneralGraph * gc = new GCoptimizationGeneralGraph(num_pixels, num_labels);
 
    for (int i = 0; i < num_pixels; i++) {
      gc->setLabel(i, (int)classes[i]);
    }
    
    gc->setDataCost(data);

	Images imgs;	
	int n_images = *((int*)mxGetData(in[5]));
 
 	imgs.images = new unsigned char* [n_images];
 	for (int i_img = 0; i_img < n_images; i_img++)
 		imgs.images[i_img] =  (unsigned char *)mxGetData(mxGetCell(in[6], i_img));	
 
	gc->setSmoothCost(smooth_cost, (void*)(&imgs));			

    /* Set spatialy varying part of the smoothness cost with the neighborhood 
     */
    mwSize total = 0;
    double * pair = mxGetPr(in[IN_PAIRWISE]);
    mwIndex * ir = mxGetIr(in[IN_PAIRWISE]);
    mwIndex * jc = mxGetJc(in[IN_PAIRWISE]);
    for (int col=0; col < num_pixels; col++) {
      mwIndex starting_row_index = jc[col];
      mwIndex stopping_row_index = jc[col+1];
      if (starting_row_index == stopping_row_index)
        continue;
      
      for (int idx = starting_row_index; idx < stopping_row_index; idx++) {
        /* only set bottom triangle of pairwise, per GC_README */
        if ( ir[idx] > col )
          gc->setNeighbors(ir[idx], col, pair[total]);
        total++;
      }
    }

    *energy = gc->compute_energy();

    /* From GC_README 
     * The expansion algorithm for energy minimization can be used whenever for
     * any 3 labels a,b,c V(a,a) + V(b,c) <= V(a,c)+V(b,a). In other words,
     * expansion algorithm can be used if the binary energy for the expansion
     * algorithm step is regular, using V. Kolmogorov's terminology.
     *
     * The swap algorithm for energy minimization can be used whenever for any 2
     * labels a,b V(a,a) + V(b,b) <= V(a,b)+V(b,a). In other words, swap
     * algorithm can be used if the binary energy for the swap algorithm step is
     * regular, using V. Kolmogorov's terminology.
     */

    if(expansion)
      gc->expansion();
    else
      gc->swap();

    *energy_after = gc->compute_energy();

    for (int i = 0; i < num_pixels; i++ )
      labels[i] = gc->whatLabel(i);

    delete gc;	
	delete[] imgs.images;
  }
  catch (GCException e) {
    mexErrMsgTxt(e.message);
  }

}
Example #29
0
void mexFunction(
    int          nlhs,
    mxArray*      plhs[],
    int          nrhs,
    const mxArray* prhs[]
) {

    char* filename;
    int first_frame, last_frame;
    bool color;
    parse_arguments(nlhs, prhs, nrhs, &filename, &first_frame, &last_frame, &color);

    Video* video = NULL;

    if (first_frame < 0) {
        std::cout << "reading all video!" << std::endl;
        video = new Video(filename);
        first_frame = 1;
        last_frame = video->frames;//frames counted by grabbing all frames in video
    } else {
        std::cout << "reading frames: " << first_frame << "-" << last_frame << std::endl;
        video = new Video(filename, last_frame - first_frame);
    }



    int n_of_dims, channels;
    mwSize* dims;
    if (!color) {
        n_of_dims = 3;
        channels = 1;
        dims = new mwSize[3];
        dims[1] = video->getWidth();
        dims[0] = video->getHeight();
        dims[2] = last_frame - first_frame + 1 ;
    } else {
        n_of_dims = 4;
        channels = 3;
        dims = new mwSize[4];
        dims[1] = video->getWidth();
        dims[0] = video->getHeight();
        dims[3] = last_frame - first_frame + 1 ;
        dims[2] = 3;
    }
    IplImage* img = 0;

    //create 3 dimensional storage and assign it to output arguments
    plhs[0] = mxCreateNumericArray(n_of_dims, dims , mxUINT8_CLASS, mxREAL);
    //get pointer to data (cast necessary since data is not double, mxGetData returns a void*)
    unsigned char* video_ptr = (unsigned char*)mxGetData(plhs[0]);


    //frame counter
    int f = 0;
    //we skip frames until f == first_frame (we want to grab from here)
    //and we stop grabbing after f == last_frame
    while ((img = video->getNextFrame()) && f < last_frame) {
        ++f;
        //check if we are in the correct range (following annotation)
        if (f >= first_frame) { // && f <= last_frame ... no need to check this after last_frame we grab the last one
            video->convertFrame(video_ptr, img, color);
            //move pointer ahead one frame
            video_ptr += video->getHeight() * video->getWidth() * channels;
        }
    }
    mxFree(filename);
    return;
}
Example #30
0
void
mexFunction(int nout, mxArray *out[],
            int nin, const mxArray *in[])
{
  enum {IN_DATA, IN_LABELS, IN_LAMBDA, IN_END} ;
  enum {OUT_MODEL = 0, OUT_BIAS, OUT_INFO} ;

  int verbose = 0 ;
  int opt ;
  int next = IN_END ;
  mxArray const *optarg ;

  mxArray *inputModel = NULL;
  VlSvmPegasos* svm = NULL ;

  vl_bool freeModel = VL_TRUE ;
  vl_size dataDimension ;

  vl_uint32* matlabPermutation ;

  void * data ;
  mxClassID dataClass ;
  vl_type dataType ;
  vl_size numSamples ;

  vl_uint32 * permutation  = NULL ;
  vl_size permutationSize = 0 ;

  DiagnosticsDispatcher* disp ;
  VlSvmDatasetInnerProduct innerProduct = NULL ;
  VlSvmDatasetAccumulator accumulator = NULL ;

  /* maps */
  VlSvmDatasetFeatureMap mapFunc  = NULL ;

  /* Homkermap */
  VlHomogeneousKernelType kernelType = VlHomogeneousKernelChi2 ;
  VlHomogeneousKernelMapWindowType windowType = VlHomogeneousKernelMapWindowRectangular ;
  double gamma = 1.0 ;
  int n = 0 ;
  double period = -1 ;

  VlSvmDataset* dataset ;

  vl_bool homkermap = VL_FALSE ;
  void * map = NULL ;

  VL_USE_MATLAB_ENV ;

  disp = (DiagnosticsDispatcher*) vl_malloc(sizeof(DiagnosticsDispatcher)) ;
  disp->diagnosticsHandle = NULL ;
  disp->callerRef = NULL ;
  disp->verbose = 0 ;

  /* -----------------------------------------------------------------
   *                                               Check the arguments
   * -------------------------------------------------------------- */

  if (nin < 3) {
    vlmxError(vlmxErrInvalidArgument,
              "At least three arguments are required.") ;
  } else if (nout > 3) {
    vlmxError(vlmxErrInvalidArgument,
              "Too many output arguments.");
  }

  dataClass = mxGetClassID(IN(DATA)) ;

  if (! vlmxIsMatrix (IN(DATA), -1, -1) ||
      ! vlmxIsReal (IN(DATA))) {
    vlmxError(vlmxErrInvalidArgument,
              "DATA must be a real matrix.") ;
  }

  data = mxGetData (IN(DATA)) ;
  dataDimension = mxGetM(IN(DATA)) ;
  numSamples = mxGetN(IN(DATA)) ;

  /* Get order of the HOMKERMAP, if used. */
  while ((opt = vlmxNextOption (in, nin, options, &next, &optarg)) >= 0) {
    if  (opt == opt_homkermap) {
      homkermap = VL_TRUE ;
      if (! vlmxIsPlainScalar(optarg)) {
        vlmxError(vlmxErrInvalidArgument, "N is not a scalar.") ;
      }
      n = *mxGetPr(optarg) ;
      if (n < 0) {
        vlmxError(vlmxErrInvalidArgument, "N is negative.") ;
      }
    }
  }

  next = IN_END ;

  if (! vlmxIsVector(IN(LABELS), numSamples)) {
    vlmxError(vlmxErrInvalidArgument, "LABELS is not a vector of dimension compatible with DATA.") ;
  }


  switch (dataClass) {
  case mxSINGLE_CLASS : dataType = VL_TYPE_FLOAT ; break ;
  case mxDOUBLE_CLASS : dataType = VL_TYPE_DOUBLE ; break ;
  default:
    vlmxError(vlmxErrInvalidArgument,
              "DATA must be either SINGLE or DOUBLE.") ;
  }

  if (mxGetClassID(IN(LABELS)) != mxINT8_CLASS) {
    vlmxError(vlmxErrInvalidArgument, "LABELS must be INT8.") ;
  }


  if (! vlmxIsPlainScalar(IN(LAMBDA))) {
    vlmxError(vlmxErrInvalidArgument, "LAMBDA is not a plain scalar.") ;
  }

  svm = vl_svmpegasos_new ((2*n + 1)*dataDimension,*mxGetPr(IN(LAMBDA))) ;

  while ((opt = vlmxNextOption (in, nin, options, &next, &optarg)) >= 0) {
    switch (opt) {
    case opt_bias_multiplier :
      if (!vlmxIsPlainScalar(optarg)) {
        vlmxError(vlmxErrInvalidArgument, "BIASMULTIPLIER is not a plain scalar.") ;
      }
      vl_svmpegasos_set_bias_multiplier(svm, *mxGetPr(optarg)) ;
      break ;

    case opt_max_iterations :
      if (!vlmxIsPlainScalar(optarg)) {
        vlmxError(vlmxErrInvalidArgument, "MAXITERATIONS is not a plain scalar.") ;
      }
      if (*mxGetPr(optarg) < 0) {
        vlmxError(vlmxErrInvalidArgument, "MAXITERATIONS is negative.") ;
      }
      vl_svmpegasos_set_maxiterations(svm, (vl_size) *mxGetPr(optarg)) ;
      break ;

    case opt_epsilon :
      if (!vlmxIsPlainScalar(optarg)) {
        vlmxError(vlmxErrInvalidArgument, "EPSILON is not a plain scalar.") ;
      }
      if (*mxGetPr(optarg) < 0) {
        vlmxError(vlmxErrInvalidArgument, "EPSILON is negative.") ;
      }
      vl_svmpegasos_set_epsilon(svm, (double) *mxGetPr(optarg)) ;
      break ;

    case opt_starting_iteration :
      if (!vlmxIsPlainScalar(optarg)) {
        vlmxError(vlmxErrInvalidArgument, "STARTINGITERATION is not a plain scalar.") ;
      }
      if (*mxGetPr(optarg) < 1) {
        vlmxError(vlmxErrInvalidArgument, "STARTINGITERATION is smaller than 1.") ;
      }
      vl_svmpegasos_set_iterations(svm, (vl_size) *mxGetPr(optarg) - 1) ;
      break ;

    case opt_starting_model :
      if (!vlmxIsVector(optarg, -1) ||
          mxIsComplex(optarg) ||
          mxGetClassID(optarg) != mxDOUBLE_CLASS) {
        vlmxError(vlmxErrInvalidArgument, "STARTINGMODEL is not a real vector.") ;
      }
      inputModel = mxDuplicateArray(optarg) ;
      vl_svmpegasos_set_model(svm,(double*) mxGetData(inputModel)) ;
      freeModel = VL_FALSE ;
      break ;

    case opt_starting_bias :
      if (!vlmxIsPlainScalar(optarg)) {
        vlmxError(vlmxErrInvalidArgument, "STARTINGBIAS is not a plain scalar.") ;
      }
      vl_svmpegasos_set_bias(svm, (double) *mxGetPr(optarg)) ;
      break ;

    case opt_permutation :
      if (!vlmxIsVector(optarg, -1) ||
          mxIsComplex(optarg) ||
          mxGetClassID(optarg) != mxUINT32_CLASS) {
        vlmxError(vlmxErrInvalidArgument, "PERMUTATION is not a UINT32 vector.") ;
      }
      permutationSize = mxGetNumberOfElements(optarg) ;
      permutation = mxMalloc(sizeof(vl_uint32) * permutationSize) ;
      matlabPermutation = mxGetData(optarg) ;
      {
        /* adjust indexing */
        vl_uindex k ;
        for (k = 0 ; k < permutationSize ; ++k) {
          permutation[k] = matlabPermutation[k] - 1 ;
          if (permutation[k] >= numSamples) {
            vlmxError(vlmxErrInconsistentData,
                      "Permutation indexes out of bounds: PERMUTATION(%d) = %d > %d = number of data samples.",
                      k + 1, permutation[k] + 1, numSamples) ;
          }
        }
      }
      vl_svmpegasos_set_permutation(svm,permutation,permutationSize) ;
      break ;

    case opt_bias_learningrate :
      if (!vlmxIsPlainScalar(optarg)) {
        vlmxError(vlmxErrInvalidArgument, "BIASLEARNINGRATE is not a plain scalar.") ;
      }
      if (mxGetClassID(optarg) != mxDOUBLE_CLASS) {
        vlmxError(vlmxErrInvalidArgument, "BIASLEARNINGRATE must be double.") ;
      }
      vl_svmpegasos_set_bias_learningrate(svm, (double)*mxGetPr(optarg)) ;
      break ;
    case opt_diagnostic :

      if( !mxIsClass( optarg , "function_handle")) {
        mexErrMsgTxt("DIAGNOSTICSFUNCTION must be  a function handle.");
      }
      disp->diagnosticsHandle = (mxArray*)(optarg) ;
      break ;

    case opt_diagnostic_caller_ref :
      disp->callerRef = (mxArray*)(optarg) ;
      break ;

    case opt_energy_freq :
      if (!vlmxIsPlainScalar(optarg)) {
        vlmxError(vlmxErrInvalidArgument, "ENERGYFREQ is not a plain scalar.") ;
      }
      vl_svmpegasos_set_energy_frequency (svm, (vl_size)*mxGetPr(optarg)) ;
      break ;

    case opt_verbose :
      ++ verbose ;
      disp->verbose = 1 ;
      break ;

    case opt_KINTERS:
    case opt_KL1:
      kernelType = VlHomogeneousKernelIntersection ;
      break ;

    case opt_KCHI2:
      kernelType = VlHomogeneousKernelChi2 ;
      break ;

    case opt_KJS:
      kernelType = VlHomogeneousKernelJS ;
      break ;

    case opt_period:
      if (! vlmxIsPlainScalar(optarg)){
        vlmxError(vlmxErrInvalidArgument, "PERIOD is not a scalar.") ;
      }
      period = *mxGetPr(optarg) ;
      if (period <= 0) {
        vlmxError(vlmxErrInvalidArgument, "PERIOD is not positive.") ;
      }
      break ;

    case opt_gamma:
      if (! vlmxIsPlainScalar(optarg)){
        vlmxError(vlmxErrInvalidArgument, "GAMMA is not a scalar.") ;
      }
      gamma = *mxGetPr(optarg) ;
      if (gamma <= 0) {
        vlmxError(vlmxErrInvalidArgument, "GAMMA is not positive.") ;
      }
      break ;

    case opt_window:
      if (! vlmxIsString(optarg,-1)){
        vlmxError(vlmxErrInvalidArgument, "WINDOW is not a string.") ;
      } else {
        char buffer [1024] ;
        mxGetString(optarg, buffer, sizeof(buffer) / sizeof(char)) ;
        if (vl_string_casei_cmp("uniform", buffer) == 0) {
          windowType = VlHomogeneousKernelMapWindowUniform ;
        } else if (vl_string_casei_cmp("rectangular", buffer) == 0) {
          windowType = VlHomogeneousKernelMapWindowRectangular ;
        } else {
          vlmxError(vlmxErrInvalidArgument, "WINDOW=%s is not recognized.", buffer) ;
        }
      }
      break ;
    }
  }

  if (verbose) {
    mexPrintf("vl_pegasos: Lambda = %g\n", svm->lambda) ;
    mexPrintf("vl_pegasos: BiasMultiplier = %g\n", svm->biasMultiplier) ;
    mexPrintf("vl_pegasos: MaxIterations = %d\n", svm->maxIterations) ;
    mexPrintf("vl_pegasos: permutation size = %d\n", permutationSize) ;
  }

  switch (dataType) {
  case VL_TYPE_FLOAT :
    innerProduct = (VlSvmDatasetInnerProduct)&vl_svmdataset_innerproduct_f ;
    accumulator = (VlSvmDatasetAccumulator)&vl_svmdataset_accumulator_f ;
    break ;
  case VL_TYPE_DOUBLE:
    innerProduct = (VlSvmDatasetInnerProduct)&vl_svmdataset_innerproduct_d ;
    accumulator = (VlSvmDatasetAccumulator)&vl_svmdataset_accumulator_d ;
    break ;
  }

  dataset = vl_svmdataset_new(data,dataDimension) ;
  if (homkermap) {
    map = vl_homogeneouskernelmap_new (kernelType, gamma, n, period, windowType) ;
    mapFunc = (VlSvmDatasetFeatureMap)&vl_homogeneouskernelmap_evaluate_d ;
    vl_svmdataset_set_map(dataset,map,mapFunc,2*n + 1) ;
  }

  /* -----------------------------------------------------------------
   *                                                            Do job
   * -------------------------------------------------------------- */
  if (disp->diagnosticsHandle) {
    vl_svmpegasos_set_diagnostic (svm, (VlSvmDiagnostics)&diagnosticDispatcher, disp) ;
  }

  vl_svmpegasos_train (svm,dataset, numSamples,innerProduct, accumulator,
                       (vl_int8 const *)mxGetData(IN(LABELS))) ;

  /* -----------------------------------------------------------------
   *                                                            Output
   * -------------------------------------------------------------- */

  if (nout >= 1) {
    double * tempBuffer ;
    mwSize dims[2] ;
    dims[0] = svm->dimension ;
    dims[1] = 1 ;
    out[OUT_MODEL] = mxCreateNumericArray(2, dims,
                                          mxDOUBLE_CLASS, mxREAL) ;
    tempBuffer  = (double*) mxGetData(out[OUT_MODEL]) ;
    memcpy(tempBuffer,svm->model,svm->dimension * sizeof(double)) ;
  }

  if (nout >= 2) {
    double * tempBuffer ;
    mwSize dims[2] ;
    dims[0] = 1 ;
    dims[1] = 1 ;

    out[OUT_BIAS] = mxCreateNumericArray(2, dims,
                                         mxDOUBLE_CLASS, mxREAL) ;
    tempBuffer = (double*) mxGetData(out[OUT_BIAS]) ;
    *tempBuffer = svm->bias ;
  }

  if (nout == 3) {
    out[OUT_INFO] = createInfoStruct(svm) ;
  }

  if (homkermap) {
    vl_homogeneouskernelmap_delete(map);
  }
  vl_svmdataset_delete(dataset) ;
  vl_svmpegasos_delete(svm,freeModel) ;
  vl_free(disp) ;
}