Exemplo n.º 1
0
static void mdlOutputs(SimStruct *S, int_T tid)
{
    /*--------Define Parameters-------*/
    const real_T s_T_Nc             = *mxGetPr(s_T_Nc_p(S));
    const real_T s_T_PR             = *mxGetPr(s_T_PR_p(S));
    const real_T s_T_Wc             = *mxGetPr(s_T_Wc_p(S));
    const real_T s_T_Eff            = *mxGetPr(s_T_Eff_p(S));
    const real_T NcDes              = *mxGetPr(NcDes_p(S));
    const real_T PRmapDes           = *mxGetPr(PRmapDes_p(S));
    const real_T EffDes             = *mxGetPr(EffDes_p(S));
    const real_T NDes               = *mxGetPr(NDes_p(S));
    const real_T IDes               = *mxGetPr(IDesign_p(S));
    const int_T  BldPosLeng         = *mxGetPr(BldPosLeng_p(S));
    const int_T  CoolFlwEn          = *mxGetPr(CoolFlwEn_p(S));

    /* vector & array data */
    const real_T *Y_T_NcVec            = mxGetPr(Y_T_NcVec_p(S));
    const real_T *X_T_PRVec            = mxGetPr(X_T_PRVec_p(S));
    const real_T *T_T_Map_WcArray      = mxGetPr(T_T_Map_WcArray_p(S));
    const real_T *T_T_Map_EffArray     = mxGetPr(T_T_Map_EffArray_p(S));
    const real_T *T_BldPos             = mxGetPr(T_BldPos_p(S));

    /*------get dimensions of parameter arrays-------*/
    const int_T A   = mxGetNumberOfElements(Y_T_NcVec_p(S));
    const int_T B   = mxGetNumberOfElements(X_T_PRVec_p(S));

    /*---------Define Inputs--------*/
    const real_T *u  = (const real_T*) ssGetInputPortSignal(S,0);

    double WIn      = u[0];     /* Input Flow [pps]	*/
    double htIn     = u[1];     /* input enthalpy [BTU/lbm]*/
    double TtIn     = u[2];     /* Temperature Input [degR]  */
    double PtIn     = u[3];     /* Pressure Input [psia] 	 */
    double FARcIn   = u[4];     /* Compusted Fuel to Air Ratio [frac] */
    double Nmech    = u[5];     /* Mechancial Shaft Speed [rpm]*/
    double PRIn     = u[6];     /* Pressure Ratio [NA] 	 */

    /*---------Define Inputs for input port 2--------*/
    /* N 5x1 vectors consisting of W, ht, Tt, Pt and FAR, where N is the number of cooling flows */
    const real_T *CoolFlow = ssGetInputPortRealSignal(S, 1);
    int cfWidth = ssGetCurrentInputPortDimensions(S, 1, 0);

    real_T *y  = (real_T *)ssGetOutputPortRealSignal(S,0);   /* Output Array */

    /*--------Define Constants-------*/
    double WOut, htOut, TtOut, PtOut, FARcOut, TorqueOut, NErrorOut;
    double WcCalcin, WcMap, theta,delta, Pwrout, PRin, htin;
    double TtIdealout, Test, htIdealout, Sout, NcMap, Nc, EffMap, Eff;
    double dHcools1, dHcoolout, Wfcools1, Wfcoolout, Ws1in,hts1in, Tts1in, Pts1in, FARs1in;
    double Ss1in, dHout, Wcoolout, Wcools1, PRmapRead;
    double C_Eff, C_PR, C_Nc, C_Wc;

    int interpErr = 0;
    double Wcool[100];
    double htcool[100];
    double Ttcool[100];
    double Ptcool[100];
    double FARcool[100];
    int Vtest, i;

    /* ------- get strings -------------- */
    char * BlkNm;
    int_T buflen;
    int_T status;

    /* Get name of block from dialog parameter (string) */
    buflen = mxGetN(BN_p(S))*sizeof(mxChar)+1;
    BlkNm = mxMalloc(buflen);
    status = mxGetString(BN_p(S), BlkNm, buflen);

    /* Verify input bleed vector is a multiple of 5 */
    Vtest = cfWidth/5;
    if(5*Vtest != cfWidth && CoolFlwEn > 0.5 && ssGetIWork(S)[0]==0){
        printf("Error in %s, one or more of the cooling flow input vector eleements is missing(Vector form; 5x1: W,ht,Tt,Pt,FAR)\n",BlkNm);
        ssSetIWorkValue(S,0,1);
    }
    else if(BldPosLeng != cfWidth/5 && CoolFlwEn > 0.5 && ssGetIWork(S)[1]==0){
        printf("Errorin %s, number of cooling flow inputs does not match the length of the Cooling flow postion vector in the mask\n",BlkNm);
        ssSetIWorkValue(S,1,1);
    }

    /* unpack CoolFlow vector */
    for (i = 0; i < cfWidth/5; i++)
    {
        if (CoolFlwEn < 0.5){
            Wcool[i] = 0;
            htcool[i] = 0;
            Ttcool[i] = 0;
            Ptcool[i] = 0;
            FARcool[i] = 0;
        }
        else {
            Wcool[i] = CoolFlow[5*i];
            Ttcool[i] = CoolFlow[5*i+2];
            Ptcool[i] = CoolFlow[5*i+3];
            FARcool[i] = CoolFlow[5*i+4];
            htcool[i] = t2hc(Ttcool[i],FARcool[i]);
        }
    }

    /* Initialize cooling flow sum constants */

    dHcools1 = 0;   /* enthalpy * mass cooling flow rate at stage 1 of turbine */
    dHcoolout = 0;   /* enthalpy * mass cooling flow rate at exit of turbine */
    Wcools1 = 0;    /* total cooling flow at stage 1 of turbine*/
    Wcoolout = 0;    /* total cooling flow at output of turbine */
    Wfcools1 = 0;  /* combusted fuel flow in cooling at stage 1 of turbine */
    Wfcoolout = 0;  /* combusted fuel flow in cooling at exit of turbine */

    /* calc cooling flow constants for stage 1 and output of the turbine */
    for (i = 0; i < cfWidth/5; i++)
    {
        if ((T_BldPos[i] > 1 || T_BldPos[i] < 0) && CoolFlwEn > 0.5 && ssGetIWork(S)[2]==0){
            printf(" Error in %s, cooling flow postion element %i needs to be defined as a 0 or 1\n",BlkNm,i+1);
            ssSetIWorkValue(S,2,1);
        }

        /* calc mass flow for cooling flows */
        Wcools1 = Wcools1 + Wcool[i]*(1-T_BldPos[i]);
        Wcoolout = Wcoolout + Wcool[i];

        /* calc fuel mass flow for cooling flows*/
        Wfcools1 = Wfcools1 + FARcool[i]*Wcool[i]*(1-T_BldPos[i])/(1+FARcool[i]);
        Wfcoolout = Wfcoolout + FARcool[i]*Wcool[i]/(1+FARcool[i]);
    }
    /*-- Compute Total Flow  --------*/

    Ws1in = WIn + Wcools1;  /* mass flow at station 1 */
    WOut = WIn + Wcoolout;   /* mass flow at turbine exit */

    /*-- Compute Fuel to Air Ratios ---*/

    FARs1in = (FARcIn* WIn/(1+FARcIn) + Wfcools1)/(WIn/(1+FARcIn) + Wcools1- Wfcools1);
    FARcOut = (FARcIn* WIn/(1+FARcIn)+ Wfcoolout)/(WIn/(1+FARcIn) + Wcoolout- Wfcoolout);

    /* calc input enthalpy of cooling flow for stage 1 */
    for (i = 0; i < cfWidth/5; i++)
    {
        /* Compute cooling flow dH at stage 1  */
        dHcools1 = dHcools1 + htcool[i]*Wcool[i]*(1-T_BldPos[i]);
        /* Compute cooling flow dH for the exit of the turbine assuming input htcool = htcoolout for turbine rear bleeds  */
        dHcoolout = dHcoolout + htcool[i]*Wcool[i]*T_BldPos[i];
    }

    /*-- Compute avg enthalpy at stage 1 --------*/
    htin = t2hc(TtIn,FARcIn);
    hts1in = (htin* WIn + dHcools1)/Ws1in;

    /*-- Compute  stage 1 total temp--------*/

    Tts1in = h2tc(hts1in,FARs1in);

    /*-- Compute Stage 1 entropy, assuming PtIn = Pts1in  --------*/
    Ss1in = pt2sc(PtIn,Tts1in,FARs1in);

    /*---- calculate misc. fluid condition related variables --------*/
    delta = PtIn / C_PSTD;
    theta = TtIn / C_TSTD;

    /*------ Calculate corrected speed ---------*/
    Nc = Nmech/sqrt(theta);

    if(IDes < 0.5)
        C_Nc = Nc / NcDes;
    else
        C_Nc = s_T_Nc;

    NcMap = Nc / C_Nc;

    /*------ Compute pressure output --------*/
    if(IDes < 0.5)
        C_PR = (PRIn - 1)/(PRmapDes -1);
    else
        C_PR = s_T_PR;

    PRmapRead = ((PRIn -1)/C_PR)+1;

    PtOut = PtIn/PRIn;	/* using PR from input */

    /*-- Compute Total Flow input (from Turbine map)  --------*/

    WcMap = interp2Ac(X_T_PRVec,Y_T_NcVec,T_T_Map_WcArray,PRmapRead,NcMap,B,A,&interpErr);
    if (interpErr == 1 && ssGetIWork(S)[3]==0){
        printf("Warning in %s, Error calculating WcMap. Vector definitions may need to be expanded.\n", BlkNm);
        ssSetIWorkValue(S,3,1);
    }
    if(IDes < 0.5)
        C_Wc = Ws1in*sqrt(theta)/delta / WcMap;
    else
        C_Wc = s_T_Wc;

    WcCalcin = WcMap * C_Wc;

    /*-- Compute Turbine Efficiency (from Turbine map)  --------*/

    EffMap = interp2Ac(X_T_PRVec,Y_T_NcVec,T_T_Map_EffArray,PRmapRead,NcMap,B,A,&interpErr);
    if (interpErr == 1 && ssGetIWork(S)[4]==0){
        printf("Warning in %s, Error calculating EffMap. Vector definitions may need to be expanded.\n", BlkNm);
        ssSetIWorkValue(S,4,1);
    }
    if(IDes < 0.5)
        C_Eff = EffDes / EffMap;
    else
        C_Eff = s_T_Eff;

    Eff = EffMap * C_Eff;


    /*------ enthalpy calculations ---------*/
    /* ---- Ideal enthalpy  ----*/
    Sout = Ss1in;
    TtIdealout = sp2tc(Sout,PtOut,FARcOut);
    htIdealout = t2hc(TtIdealout,FARcOut); /* may need to be updated due to TtIdealout not being correct */

    /*-Compute power output only takes into account cooling flow that enters at front of engine (stage 1)-*/

    Pwrout = ((hts1in - htIdealout)*Eff)*Ws1in * C_BTU_PER_SECtoHP;

    /* ---- enthalpy output ----*/

    htOut = ((((htIdealout - hts1in)*Eff) + hts1in)*Ws1in + dHcoolout)/WOut;

    /*------ Compute Temperature output (empirical) ---------*/

    TtOut = h2tc(htOut,FARcOut);

    /*----- Compute output Torque to shaft ----*/
    TorqueOut = C_HP_PER_RPMtoFT_LBF * Pwrout/Nmech;

    /* ----- Compute Normalized Flow Error ----- */
    if (IDes < 0.5 && NDes == 0)
        NErrorOut = 100;
    else if (IDes < 0.5)
        NErrorOut = (Nmech - NDes)/NDes;
    else if (Ws1in == 0) {
        NErrorOut = 100;
    }
    else {
        NErrorOut = (Ws1in*sqrt(theta)/delta-WcCalcin)/(Ws1in*sqrt(theta)/delta) ;
    }
    Test = Wcool[0];
    /*------Assign output values------------        */
    y[0] = WOut;            /* Outlet Total Flow [pps]   */
    y[1] = htOut;           /* Outlet Enthalpy [BTU/lbm]*/
    y[2] = TtOut;           /* Outlet Temperature [degR]      */
    y[3] = PtOut;           /* Outlet Pressure  [psia]     */
    y[4] = FARcOut;         /* Outlet Fuel to Air Ratio [NA]	*/
    y[5] = TorqueOut;       /* Torque Output [lbf*ft]       */
    y[6] = NErrorOut;       /* Normalized turbine Error [frac]*/
    y[7] = C_Nc;            /* Corrected Shaft Speed Scalar */
    y[8] = C_Wc;            /* Corrected Flow Scalar */
    y[9] = C_PR;            /* Pressure Ratio Scalar */
    y[10] = C_Eff;          /* Efficiency Scalar */
    y[11] = Test;

}
Exemplo n.º 2
0
mxArray *ssmult_dot     /* returns C = A'*B */
(
    const mxArray *A,
    const mxArray *B,
    int ac,             /* if true: conj(A)   if false: A. ignored if A real */
    int bc,             /* if true: conj(B)   if false: B. ignored if B real */
    int cc              /* if true: conj(C)   if false: C. ignored if C real */
)
{
    double cx, cz, ax, az, bx, bz ;
    mxArray *C ;
    double *Ax, *Az, *Bx, *Bz, *Cx, *Cz ;
    Int *Ap, *Ai, *Bp, *Bi, *Cp, *Ci ;
    Int m, n, k, cnzmax, i, j, p, paend, pbend, ai, bi, cnz, pa, pb, zallzero,
        A_is_complex, B_is_complex, C_is_complex ;

    /* ---------------------------------------------------------------------- */
    /* get inputs */
    /* ---------------------------------------------------------------------- */

    m = mxGetM (A) ;
    n = mxGetN (A) ;
    k = mxGetN (B) ;

    if (m != mxGetM (B)) ssmult_invalid (ERROR_DIMENSIONS) ;

    Ap = mxGetJc (A) ;
    Ai = mxGetIr (A) ;
    Ax = mxGetPr (A) ;
    Az = mxGetPi (A) ;
    A_is_complex = mxIsComplex (A) ;

    Bp = mxGetJc (B) ;
    Bi = mxGetIr (B) ;
    Bx = mxGetPr (B) ;
    Bz = mxGetPi (B) ;
    B_is_complex = mxIsComplex (B) ;

    /* ---------------------------------------------------------------------- */
    /* allocate C as an n-by-k full matrix but do not initialize it */
    /* ---------------------------------------------------------------------- */

    /* NOTE: integer overflow cannot occur here, because this function is not
       called unless O(n*k) is less than O(m+nnz(A)).  The test is done
       in the caller, not here.
     */

    cnzmax = n*k ;
    cnzmax = MAX (cnzmax, 1) ;
    Cx = mxMalloc (cnzmax * sizeof (double)) ;
    C_is_complex = A_is_complex || B_is_complex ;
    Cz = C_is_complex ?  mxMalloc (cnzmax * sizeof (double)) : NULL ;

    /* ---------------------------------------------------------------------- */
    /* C = A'*B using sparse dot products */
    /* ---------------------------------------------------------------------- */

    /*
       NOTE:  this method REQUIRES the columns of A and B to be sorted on input.
       That is, the row indices in each column must appear in ascending order.
       This is the standard in all versions of MATLAB to date, and likely will
       be for some time.  However, if MATLAB were to use unsorted sparse
       matrices in the future (a lazy sort) then a test should be included in
       ssmult to not use ssmult_dot if A or B are unsorted, or they should be
       sorted on input.
     */

    cnz = 0 ;
    for (j = 0 ; j < k ; j++)
    {
        for (i = 0 ; i < n ; i++)
        {
            /* compute C (i,j) = A (:,i)' * B (:,j) */
            pa = Ap [i] ;
            paend = Ap [i+1] ;
            pb = Bp [j] ;
            pbend = Bp [j+1] ;

            if (pa == paend            /* nnz (A (:,i)) == 0 */
            || pb == pbend             /* nnz (B (:,j)) == 0 */
            || Ai [paend-1] < Bi [pb]  /* max(find(A(:,i)))<min(find(B(:,j))) */
            || Ai [pa] > Bi [pbend-1]) /* min(find(A(:,i)))>max(find(B(:,j))) */
            {
                Cx [i+j*n] = 0 ;        /* no work to do */
                if (C_is_complex) 
                {
                    Cz [i+j*n] = 0 ;
                }
                continue ;
            }
            cx = 0 ;
            cz = 0 ;
            while (pa < paend && pb < pbend)
            {
                /* The dot product looks like the merge in mergesort, except */
                /* no "clean-up" phase is need when one list is exhausted. */
                ai = Ai [pa] ;
                bi = Bi [pb] ;
                if (ai == bi)
                {
                    /* c += A (ai,i) * B (ai,j), and "consume" both entries */
                    if (!C_is_complex)
                    {
                        cx += Ax [pa] * Bx [pb] ;
                    }
                    else
                    {
                        /* complex case */
                        ax = Ax [pa] ;
                        bx = Bx [pb] ;
                        az = Az ? (ac ? (-Az [pa]) : Az [pa]) : 0.0 ;
                        bz = Bz ? (bc ? (-Bz [pb]) : Bz [pb]) : 0.0 ;
                        cx += ax * bx - az * bz ;
                        cz += az * bx + ax * bz ;
                    }
                    pa++ ;
                    pb++ ;
                }
                else if (ai < bi)
                {
                    /* consume A(ai,i) and discard it, since B(ai,j) is zero */
                    pa++ ;
                }
                else
                {
                    /* consume B(bi,j) and discard it, since A(ai,i) is zero */
                    pb++ ;
                }
            }
            Cx [i+j*n] = cx ;
            if (C_is_complex)
            {
                Cz [i+j*n] = cz ;
            }
        }

        /* count the number of nonzeros in C(:,j) */
        for (i = 0 ; i < n ; i++)
        {
            /* This could be done above, except for the gcc compiler bug when
               cx is an 80-bit nonzero in register above, but becomes zero here
               when stored into memory.  We need the latter, to correctly handle
               the case when cx underflows to zero in 64-bit floating-point.
               Do not attempt to "optimize" this code by doing this test above,
               unless the gcc compiler bug is fixed (as of gcc version 4.1.0).
             */
            if (Cx [i+j*n] != 0 || (C_is_complex && Cz [i+j*n] != 0))
            {
                cnz++ ;
            }
        }
    }

    /* ---------------------------------------------------------------------- */
    /* convert C to real if the imaginary part is all zero */
    /* ---------------------------------------------------------------------- */

    if (C_is_complex)
    {
        zallzero = 1 ;
        for (p = 0 ; zallzero && p < cnzmax ; p++)
        {
            if (Cz [p] != 0)
            {
                zallzero = 0 ;
            }
        }
        if (zallzero)
        {
            /* the imaginary part of C is all zero */
            C_is_complex = 0 ;
            mxFree (Cz) ;
            Cz = NULL ;
        }
    }

    /* ---------------------------------------------------------------------- */
    /* allocate integer part of C but do not initialize it */
    /* ---------------------------------------------------------------------- */

    cnz = MAX (cnz, 1) ;
    C = mxCreateSparse (0, 0, 0, C_is_complex ? mxCOMPLEX : mxREAL) ;
    mxFree (mxGetJc (C)) ;
    mxFree (mxGetIr (C)) ;
    mxFree (mxGetPr (C)) ;
    mxFree (mxGetPi (C)) ;
    Cp = mxMalloc ((k + 1) * sizeof (Int)) ;
    Ci = mxMalloc (cnz * sizeof (Int)) ;
    mxSetJc (C, Cp) ;
    mxSetIr (C, Ci) ;
    mxSetM (C, n) ;
    mxSetN (C, k) ;

    /* ---------------------------------------------------------------------- */
    /* C = sparse (C).  Note that this is done in-place. */
    /* ---------------------------------------------------------------------- */

    p = 0 ;
    for (j = 0 ; j < k ; j++)
    {
        Cp [j] = p ;
        for (i = 0 ; i < n ; i++)
        {
            cx = Cx [i+j*n] ;
            cz = (C_is_complex ? Cz [i+j*n] : 0) ;
            if (cx != 0 || cz != 0)
            {
                Ci [p] = i ;
                Cx [p] = cx ;
                if (C_is_complex) Cz [p] = (cc ? (-cz) : cz) ;
                p++ ;
            }
        }
    }
    Cp [k] = p ;

    /* ---------------------------------------------------------------------- */
    /* reduce the size of Cx and Cz and return result */
    /* ---------------------------------------------------------------------- */

    if (cnz < cnzmax)
    {
        Cx = mxRealloc (Cx, cnz * sizeof (double)) ;
        if (C_is_complex)
        {
            Cz = mxRealloc (Cz, cnz * sizeof (double)) ;
        }
    }

    mxSetNzmax (C, cnz) ;
    mxSetPr (C, Cx) ;
    if (C_is_complex)
    {
        mxSetPi (C, Cz) ;
    }
    return (C) ;
}
/** @brief MATLAB Driver.
 **/
void
mexFunction(int nout, mxArray *out[], 
            int nin, const mxArray *in[])
{
  int M,N,S=0,smin=0,K,num_levels=0 ;
  const int* dimensions ;
  const double* P_pt ;
  const double* G_pt ;
  float* descr_pt ;
  float* buffer_pt ;
  float sigma0 ;
  float magnif = 3.0f ; /* Spatial bin extension factor. */
  int NBP = 4 ;         /* Number of bins for one spatial direction (even). */
  int NBO = 8 ;         /* Number of bins for the ortientation. */
  int mode = NOSCALESPACE ;
  int buffer_size=0;

  enum {IN_G=0,IN_P,IN_SIGMA0,IN_S,IN_SMIN} ;
  enum {OUT_L=0} ;

  /* ------------------------------------------------------------------
  **                                                Check the arguments
  ** --------------------------------------------------------------- */ 
 
  if (nin < 3) {
    mexErrMsgTxt("At least three arguments are required") ;
  } else if (nout > 1) {
    mexErrMsgTxt("Too many output arguments.");
  }
		
  if( !uIsRealScalar(in[IN_SIGMA0]) ) {
    mexErrMsgTxt("SIGMA0 should be a real scalar") ;
  }
	
  if(!mxIsDouble(in[IN_G]) ||
     mxGetNumberOfDimensions(in[IN_G]) > 3) {
    mexErrMsgTxt("G should be a real matrix or 3-D array") ;
  }
  
  sigma0 = (float) *mxGetPr(in[IN_SIGMA0]) ;
  
  dimensions = mxGetDimensions(in[IN_G]) ;
  M = dimensions[0] ;
  N = dimensions[1] ;
  G_pt = mxGetPr(in[IN_G]) ;
  
  P_pt = mxGetPr(in[IN_P]) ;	
  K = mxGetN(in[IN_P]) ;
  
  if( !uIsRealMatrix(in[IN_P],-1,-1)) {
    mexErrMsgTxt("P should be a real matrix") ;
  }

  if ( mxGetM(in[IN_P])  == 4) {
    /* Standard (scale space) mode */ 
    mode = SCALESPACE ;
    num_levels = dimensions[2] ;
    
    if(nin < 5) {
      mexErrMsgTxt("Five arguments are required in standard mode") ;
    }
    
    if( !uIsRealScalar(in[IN_S]) ) {
      mexErrMsgTxt("S should be a real scalar") ;
    }
    
    if( !uIsRealScalar(in[IN_SMIN]) ) {
      mexErrMsgTxt("SMIN should be a real scalar") ;
    }
    
    if( !uIsRealMatrix(in[IN_P],4,-1)) {
      mexErrMsgTxt("When the e mode P should be a 4xK matrix.") ;
    }
    
    S = (int)(*mxGetPr(in[IN_S])) ;
    smin = (int)(*mxGetPr(in[IN_SMIN])) ;
    
  } else if (  mxGetM(in[IN_P])  == 3 ) {
    mode = NOSCALESPACE ;
    num_levels = 1 ;
    S      = 1 ;
    smin   = 0 ;
  } else {
    mexErrMsgTxt("P should be either a 3xK or a 4xK matrix.") ;
  }

  /* Parse the property-value pairs */
  {
    char str [80] ;
    int arg = (mode == SCALESPACE) ? IN_SMIN + 1 : IN_SIGMA0 + 1 ;

    while(arg < nin) {
      int k ;

      if( !uIsString(in[arg],-1) ) {
        mexErrMsgTxt("The first argument in a property-value pair"
                     " should be a string") ;
      }
      mxGetString(in[arg], str, 80) ;

#ifdef WINDOWS      
      for(k = 0 ; properties[k] && strcmpi(str, properties[k]) ; ++k) ;
#else
      for(k = 0 ; properties[k] && strcasecmp(str, properties[k]) ; ++k) ;
#endif

      switch (k) {
      case PROP_NBP:
        if( !uIsRealScalar(in[arg+1]) ) {
          mexErrMsgTxt("'NumSpatialBins' should be real scalar") ;
        }
        NBP = (int) *mxGetPr(in[arg+1]) ;
        if( NBP <= 0 || (NBP & 0x1) ) {
          mexErrMsgTxt("'NumSpatialBins' must be positive and even") ;
        }
        break ;

      case PROP_NBO:
        if( !uIsRealScalar(in[arg+1]) ) {
          mexErrMsgTxt("'NumOrientBins' should be a real scalar") ;
        }
        NBO = (int) *mxGetPr(in[arg+1]) ;
        if( NBO <= 0 ) {
          mexErrMsgTxt("'NumOrientlBins' must be positive") ;
        }
        break ;

      case PROP_MAGNIF:
        if( !uIsRealScalar(in[arg+1]) ) {
          mexErrMsgTxt("'Magnif' should be a real scalar") ;
        }
        magnif = (float) *mxGetPr(in[arg+1]) ;
        if( magnif <= 0 ) {
          mexErrMsgTxt("'Magnif' must be positive") ;
        }
        break ;

      case PROP_UNKNOWN:
        mexErrMsgTxt("Property unknown.") ;
        break ;
      }
      arg += 2 ;
    }
  }
  
  /* -----------------------------------------------------------------
   *                                   Pre-compute gradient and angles
   * -------------------------------------------------------------- */
  /* Alloc two buffers and make sure their size is multiple of 128 for
   * better alignment (used also by the Altivec code below.)
   */
  buffer_size = (M*N*num_levels + 0x7f) & (~ 0x7f) ;
  buffer_pt = (float*) mxMalloc( sizeof(float) * 2 * buffer_size ) ;
  descr_pt  = (float*) mxCalloc( NBP*NBP*NBO*K,  sizeof(float)  ) ;

  {
    /* Offsets to move in the scale space. */
    const int yo = 1 ;
    const int xo = M ;
    const int so = M*N ;
    int x,y,s ;

#define at(x,y) (*(pt + (x)*xo + (y)*yo))

    /* Compute the gradient */
    for(s = 0 ; s < num_levels ; ++s) {
      const double* pt = G_pt + s*so ;
      for(x = 1 ; x < N-1 ; ++x) {
        for(y = 1 ; y < M-1 ; ++y) {
          float Dx = 0.5 * ( at(x+1,y) - at(x-1,y) ) ;
          float Dy = 0.5 * ( at(x,y+1) - at(x,y-1) ) ;
          buffer_pt[(x*xo+y*yo+s*so) + 0          ] = Dx ;
          buffer_pt[(x*xo+y*yo+s*so) + buffer_size] = Dy ;
        }
      }
    }
    
    /* Compute angles and modules */
    {
      float* pt = buffer_pt ;
      int j = 0 ;
      while (j < N*M*num_levels) {

#if defined( MACOSX ) && defined( __ALTIVEC__ )
        if( ((unsigned int)pt & 0x7) == 0 && j+3 < N*M*num_levels ) {
          /* If aligned to 128 bit and there are at least 4 pixels left */
          float4 a, b, c, d ;
          a.vec = vec_ld(0,(vector float*)(pt              )) ;
          b.vec = vec_ld(0,(vector float*)(pt + buffer_size)) ;
          c.vec = vatan2f(b.vec,a.vec) ;
          a.x[0] = a.x[0]*a.x[0]+b.x[0]*b.x[0] ;
          a.x[1] = a.x[1]*a.x[1]+b.x[1]*b.x[1] ;
          a.x[2] = a.x[2]*a.x[2]+b.x[2]*b.x[2] ;
          a.x[3] = a.x[3]*a.x[3]+b.x[3]*b.x[3] ;
          d.vec = vsqrtf(a.vec) ;
          vec_st(c.vec,0,(vector float*)(pt + buffer_size)) ;
          vec_st(d.vec,0,(vector float*)(pt              )) ;
          j += 4 ;
          pt += 4 ;
        } else {
#endif
          float Dx = *(pt              ) ;
          float Dy = *(pt + buffer_size) ;
          *(pt              ) = sqrtf(Dx*Dx + Dy*Dy) ;
          *(pt + buffer_size) = atan2f(Dy, Dx) ;
          j += 1 ;
          pt += 1 ;
#if defined( MACOSX ) && defined( __ALTIVEC__ )
        }
#endif

      }
    }
  }

  /* -----------------------------------------------------------------
   *                                                        Do the job
   * -------------------------------------------------------------- */ 
  if(K > 0) {    
    int p ;

    /* Offsets to move in the buffer */
    const int yo = 1 ;
    const int xo = M ;
    const int so = M*N ;

    /* Offsets to move in the descriptor. */
    /* Use Lowe's convention. */
    const int binto = 1 ;
    const int binyo = NBO * NBP ;
    const int binxo = NBO ;
    const int bino  = NBO * NBP * NBP ;

    for(p = 0 ; p < K ; ++p, descr_pt += bino) {
      /* The SIFT descriptor is a  three dimensional histogram of the position
       * and orientation of the gradient.  There are NBP bins for each spatial
       * dimesions and NBO  bins for the orientation dimesion,  for a total of
       * NBP x NBP x NBO bins.
       *
       * The support  of each  spatial bin  has an extension  of SBP  = 3sigma
       * pixels, where sigma is the scale  of the keypoint.  Thus all the bins
       * together have a  support SBP x NBP pixels wide  . Since weighting and
       * interpolation of  pixel is used, another  half bin is  needed at both
       * ends of  the extension. Therefore, we  need a square window  of SBP x
       * (NBP + 1) pixels. Finally, since the patch can be arbitrarly rotated,
       * we need to consider  a window 2W += sqrt(2) x SBP  x (NBP + 1) pixels
       * wide.
       */      
      const float x = (float) *P_pt++ ;
      const float y = (float) *P_pt++ ;
      const float s = (float) (mode == SCALESPACE) ? (*P_pt++) : 0.0 ;
      const float theta0 = (float) *P_pt++ ;

      const float st0 = sinf(theta0) ;
      const float ct0 = cosf(theta0) ;
      const int xi = (int) floor(x+0.5) ; /* Round-off */
      const int yi = (int) floor(y+0.5) ;
      const int si = (int) floor(s+0.5) - smin ;
      const float sigma = sigma0 * powf(2, s / S) ;
      const float SBP = magnif * sigma ;
      const int W = (int) floor( sqrt(2.0) * SBP * (NBP + 1) / 2.0 + 0.5) ;      
      int bin ;
      int dxi ;
      int dyi ;
      const float* pt ;
      float* dpt ;

      /* Check that keypoints are within bounds . */

      if(xi < 0   || 
         xi > N-1 || 
         yi < 0   || 
         yi > M-1 ||
         ((mode==SCALESPACE) && 
          (si < 0   ||
           si > dimensions[2]-1) ) )
        continue ;

      /* Center the scale space and the descriptor on the current keypoint. 
       * Note that dpt is pointing to the bin of center (SBP/2,SBP/2,0).
       */
      pt  = buffer_pt + xi*xo + yi*yo + si*so ;
      dpt = descr_pt + (NBP/2) * binyo + (NBP/2) * binxo ;
     
#define atd(dbinx,dbiny,dbint) (*(dpt + (dbint)*binto + (dbiny)*binyo + (dbinx)*binxo))
      
      /*
       * Process each pixel in the window and in the (1,1)-(M-1,N-1)
       * rectangle.
       */
      for(dxi = max(-W, 1-xi) ; dxi <= min(+W, N-2-xi) ; ++dxi) {
        for(dyi = max(-W, 1-yi) ; dyi <= min(+W, M-2-yi) ; ++dyi) {

          /* Compute the gradient. */
          float mod   = *(pt + dxi*xo + dyi*yo + 0           ) ;
          float angle = *(pt + dxi*xo + dyi*yo + buffer_size ) ;
#ifdef LOWE_COMPATIBLE
          float theta = fast_mod(-angle + theta0) ;
#else
          float theta = fast_mod(angle - theta0) ;
#endif
          /* Get the fractional displacement. */
          float dx = ((float)(xi+dxi)) - x;
          float dy = ((float)(yi+dyi)) - y;

          /* Get the displacement normalized w.r.t. the keypoint orientation
           * and extension. */
          float nx = ( ct0 * dx + st0 * dy) / SBP ;
          float ny = (-st0 * dx + ct0 * dy) / SBP ; 
          float nt = NBO * theta / (2*M_PI) ;

          /* Get the gaussian weight of the sample. The gaussian window
           * has a standard deviation of NBP/2. Note that dx and dy are in
           * the normalized frame, so that -NBP/2 <= dx <= NBP/2. */
          const float wsigma = NBP/2 ;
          float win =  expf(-(nx*nx + ny*ny)/(2.0 * wsigma * wsigma)) ;

          /* The sample will be distributed in 8 adijacient bins. 
           * Now we get the ``lower-left'' bin. */
          int binx = fast_floor( nx - 0.5 ) ;
          int biny = fast_floor( ny - 0.5 ) ;
          int bint = fast_floor( nt ) ;
          float rbinx = nx - (binx+0.5) ;
          float rbiny = ny - (biny+0.5) ;
          float rbint = nt - bint ;
          int dbinx ;
          int dbiny ;
          int dbint ;

          /* Distribute the current sample into the 8 adijacient bins. */
          for(dbinx = 0 ; dbinx < 2 ; ++dbinx) {
            for(dbiny = 0 ; dbiny < 2 ; ++dbiny) {
              for(dbint = 0 ; dbint < 2 ; ++dbint) {
                
                if( binx+dbinx >= -(NBP/2) &&
                    binx+dbinx <   (NBP/2) &&
                    biny+dbiny >= -(NBP/2) &&
                    biny+dbiny <   (NBP/2) ) {
                  float weight = win 
                    * mod 
                    * fabsf(1 - dbinx - rbinx)
                    * fabsf(1 - dbiny - rbiny)
                    * fabsf(1 - dbint - rbint) ;

                  atd(binx+dbinx, biny+dbiny, (bint+dbint) % NBO) += weight ;
                }
              }            
            }
          }
        }  
      }

      {
        /* Normalize the histogram to L2 unit length. */        
        normalize_histogram(descr_pt, descr_pt + NBO*NBP*NBP) ;
        
        /* Truncate at 0.2. */
        for(bin = 0; bin < NBO*NBP*NBP ; ++bin) {
          if (descr_pt[bin] > 0.2) descr_pt[bin] = 0.2;
        }
        
        /* Normalize again. */
        normalize_histogram(descr_pt, descr_pt + NBO*NBP*NBP) ;
      }
    }
  }

  /* Restore pointer to the beginning of the descriptors. */
  descr_pt -= NBO*NBP*NBP*K ;

  {
    int k ;
    double* L_pt ;
    out[OUT_L] = mxCreateDoubleMatrix(NBP*NBP*NBO, K, mxREAL) ;
    L_pt = mxGetPr(out[OUT_L]) ;
    for(k = 0 ; k < NBP*NBP*NBO*K ; ++k) {
      L_pt[k] = descr_pt[k] ;
    }
  }

  mxFree(descr_pt) ;  
  mxFree(buffer_pt) ;
}
Exemplo n.º 4
0
_mps_matlab_options
mps_parse_matlab_options (const mxArray * optionStruct)
{
    _mps_matlab_options options = {
        MPS_ALGORITHM_SECULAR_GA,
        MPS_OUTPUT_GOAL_APPROXIMATE,
        16,
        false
    };

    if (!optionStruct)
        return options;

    if (mxIsChar (optionStruct))
    {
        mxChar * value = mxGetChars (optionStruct);
        if (strcmp ((char*) value, "s") == 0)
            options.algorithm = MPS_ALGORITHM_SECULAR_GA;
        else if (strcmp ((char*) value, "u") == 0)
            options.algorithm = MPS_ALGORITHM_STANDARD_MPSOLVE;
        else
            mexErrMsgTxt ("Invalid value specified for the algorithm. Only 'u' or 's' are allowed.\n");
    }
    else if (! mxIsStruct (optionStruct))
        mexErrMsgTxt ("Only chars and struct values are allowed as MPSolve options\n");

    if (optionStruct)
    {
        int nFields = mxGetNumberOfFields (optionStruct);
        int i;

        for (i = 0; i < nFields; i++)
        {
            const char * optionName = mxGetFieldNameByNumber (optionStruct, i);
            mxArray * field = mxGetFieldByNumber (optionStruct, 0, i);

            if (strcmp (optionName, "algorithm") == 0)
            {
                if (! mxIsChar (field))
                    mexErrMsgTxt ("Please specify only 'u' or 's' for the algorithm property\n");
                else
                {
                    mxChar * value = mxGetChars (field);
                    if (strcmp ((char*) value, "s") == 0)
                        options.algorithm = MPS_ALGORITHM_SECULAR_GA;
                    else if (strcmp ((char*) value, "u") == 0)
                        options.algorithm = MPS_ALGORITHM_STANDARD_MPSOLVE;
                    else
                        mexErrMsgTxt ("Invalid value specified for the property: 'algorithm'. Only 'u' or 's' are allowed.\n");
                }
            }
            else if (strcmp (optionName, "digits") == 0)
            {
                if (! mxIsNumeric (field))
                    mexErrMsgTxt ("Please specify a positive integer for the digits property\n");
                else
                {
                    double digits = mxGetScalar (field);

                    if (digits <= 0)
                        mexErrMsgTxt ("Please specify a positive integer for the digits property\n");
                    else
                        options.digits = (int) digits;
                }
            }
            else if (strcmp (optionName, "goal") == 0)
            {
                if (! mxIsChar (field))
                    mexErrMsgTxt ("Please specify only 'a' or 'i' as value for the goal property\n");
                else
                {
                    mxChar * value = mxGetChars (field);
                    if (strcmp ((char*) value, "i") == 0)
                        options.goal = MPS_OUTPUT_GOAL_ISOLATE;
                    else if (strcmp ((char*) value, "a") == 0)
                        options.goal = MPS_OUTPUT_GOAL_APPROXIMATE;
                    else
                        mexErrMsgTxt ("Please specify only 'a' or 'i' as value for the goal property\n");
                }
            }
            else if (strcmp (optionName, "radius") == 0)
            {
                if (! mxIsLogicalScalar (field))
                    mexErrMsgTxt ("Please specify 'true' or 'false' as a value for the radius property\n");
                else
                {
                    options.radius = *mxGetLogicals (field);
                }
            }
            else
            {
                char * buffer = (char*) mxMalloc (sizeof (char) * (strlen ("The property '' is invalid\n") + strlen ((char*) optionName) + 1));
                sprintf (buffer, "The property '%s' is invalid\n", optionName);
                mexErrMsgTxt (buffer);
                mxFree (buffer);
            }
        }
    }

    return options;
}
Exemplo n.º 5
0
/* Gateway of minkmex */
void mexFunction(int nlhs, mxArray *plhs[],
                 int nrhs, const mxArray *prhs[]) {
    
    mwSignedIndex l, i, kout, nelem, p0, nz, nansplit, npos;
    mwSize columns, rows;
    int sparseflag; /* sparse */
    
    /* Check arguments */
    if (nrhs<2)
        mexErrMsgTxt("MINKMEX: Two input arguments required.");
    
    if (!mxIsNumeric(prhs[0]))
        mexErrMsgTxt("MINKMEX: First input LIST argument must be numeric.");
    
    sparseflag = mxIsSparse(prhs[0]); /* sparse */
    
    if (!mxIsNumeric(prhs[1]))                              
        mexErrMsgTxt("MINKMEX: Second input K must be numeric.");

    rows =  mxGetM(prhs[0]);
    columns = mxGetN(prhs[0]);
    nelem = rows*columns;
    /* Get the number of elements of the list of subindexes */
    if (sparseflag)
    {
        /* Search for the number of non-zero in sparse */      
        l = *(mxGetJc(prhs[0]) + columns);
    }
    else if (mxGetNumberOfDimensions(prhs[0])==2) /* Check for array */
        l = nelem;
    else
        mexErrMsgTxt("MINKMEX: First input LIST must be a 2D array.");
    
    if (mxGetClassID(prhs[0]) != mxDOUBLE_CLASS)
        mexErrMsgTxt("MINKMEX: First input LIST must be a double.");
    
    /* Get the number of elements of the list of subindexes */
    if (mxGetM(prhs[1])!=1 || mxGetN(prhs[1])!=1)
        mexErrMsgTxt("MINKMEX: Second input K must be a scalar.");
    
    if (mxGetClassID(prhs[1]) != mxDOUBLE_CLASS)
        mexErrMsgTxt("MINKMEX: Second input K must be a double.");
    
    kout = k = (int)(*mxGetPr(prhs[1]));
    if (k<0)
        mexErrMsgTxt("MINKMEX: K must be non-negative integer.");
    
    /* Get a data pointer */
    list = mxGetPr(prhs[0]);

    /* Clip k */
    if (k>l) k=l;
    
    /* Clip kout */
    if (kout>nelem) kout=nelem;

    /* Clean programming */
    pos=NULL;
    
    /* Work for non-empty array */
    if (l>0) {
         /* Vector of index */
        pos = mxMalloc(sizeof(mwSize)*l);
        if (pos==NULL)
            mexErrMsgTxt("Out of memory.");
        /* Initialize the array of position (zero-based index) */
        for (i=0; i<l; i++) pos[i]=i;
        
        /* Call the recursive engine */
        k--; /* because we work on zero-based */
        nansplit = partNaN(0, l-1); /* Push NaN at the end */
        if (k<nansplit && nansplit>=0)
            findFirstK(0, nansplit);
        
        /* Look for the split of positive/negative numbers */
        if (sparseflag) {
            p0 = part0(0, k); /* number of strict negative elements */
            if (p0 < k) /* There are at least two positive elements */
            {
                /* Number of implicite zeros */
                nz = nelem-l;
                if (nz) /* in case the positive set is unordered */
                {
                    k -= nz;
                    findFirstK(p0, nansplit);
                    k += nz;
                }
            }
            /* ++ to restore one-based Matlab index */
            k++; 
        }
        else
            /* ++ to Restore one-based Matlab index */
            p0 = ++k;
    } /* if (l>0) */
    else p0 = 0;
    
    /* Number of implicite zero in (sparse) */
    nz = nelem-l;
    /* Create the Matrix result (first output) */
    plhs[0] = MinMaxResult(k, p0, nz, kout);
    
     /* Create the Matrix position (second output) */
    if (nlhs>=2)
    {
        if (sparseflag)
            SpLocResult(k, p0, nz, kout, prhs[0], &(plhs[1]), &(plhs[2]));
        else
            plhs[1] = LocResult(k, p0, nz, kout);
    }
    
    /* Free the array of position */
    if (pos) mxFree(pos);
    pos = NULL; /* clean programming */
    
    return;

} /* Gateway of minkmex.c */
Exemplo n.º 6
0
void mexFunction(
    int           nlhs,           /* number of expected outputs */
    mxArray       *plhs[],        /* array of pointers to output arguments */
    int           nrhs,           /* number of inputs */
    const mxArray *prhs[]         /* array of pointers to input arguments */
)

{
	size_t 		k,k1;
	const mxArray	*arg;
	mxArray		*HDR;
	HDRTYPE		*hdr;
	CHANNEL_TYPE*	cp; 
	size_t 		count;
	time_t 		T0;
	char 		*FileName=NULL;  
	int 		status; 
	int		CHAN = 0;
	int		TARGETSEGMENT = 1; 
	double		*ChanList=NULL;
	int		NS = -1;
	char		FlagOverflowDetection = 1, FlagUCAL = 0;
	int		argSweepSel = -1;
	
#ifdef CHOLMOD_H
	cholmod_sparse RR,*rr=NULL;
	double dummy;
#endif 

// ToDO: output single data 
//	mxClassId	FlagMXclass=mxDOUBLE_CLASS;
	

	if (nrhs<1) {
#ifdef mexSOPEN
		mexPrintf("   Usage of mexSOPEN:\n");
		mexPrintf("\tHDR = mexSOPEN(f)\n");
		mexPrintf("   Input:\n\tf\tfilename\n");
		mexPrintf("   Output:\n\tHDR\theader structure\n\n");
#else
		mexPrintf("   Usage of mexSLOAD:\n");
		mexPrintf("\t[s,HDR]=mexSLOAD(f)\n");
		mexPrintf("\t[s,HDR]=mexSLOAD(f,chan)\n\t\tchan must be sorted in ascending order\n");
		mexPrintf("\t[s,HDR]=mexSLOAD(f,ReRef)\n\t\treref is a (sparse) matrix for rerefencing\n");
		mexPrintf("\t[s,HDR]=mexSLOAD(f,chan,'...')\n");
		mexPrintf("\t[s,HDR]=mexSLOAD(f,chan,'OVERFLOWDETECTION:ON')\n");
		mexPrintf("\t[s,HDR]=mexSLOAD(f,chan,'OVERFLOWDETECTION:OFF')\n");
		mexPrintf("\t[s,HDR]=mexSLOAD(f,chan,'UCAL:ON')\n");
		mexPrintf("\t[s,HDR]=mexSLOAD(f,chan,'UCAL:OFF')\n");
		mexPrintf("\t[s,HDR]=mexSLOAD(f,chan,'OUTPUT:SINGLE')\n");
		mexPrintf("\t[s,HDR]=mexSLOAD(f,chan,'TARGETSEGMENT:<N>')\n");
		mexPrintf("\t[s,HDR]=mexSLOAD(f,chan,'SWEEP',[NE, NG, NS])\n");
		mexPrintf("   Input:\n\tf\tfilename\n");
		mexPrintf("\tchan\tlist of selected channels; 0=all channels [default]\n");
		mexPrintf("\tUCAL\tON: do not calibrate data; default=OFF\n");
//		mexPrintf("\tOUTPUT\tSINGLE: single precision; default='double'\n");
		mexPrintf("\tOVERFLOWDETECTION\tdefault = ON\n\t\tON: values outside dynamic range are not-a-number (NaN)\n");
		mexPrintf("\tTARGETSEGMENT:<N>\n\t\tselect segment <N> in multisegment files (like Nihon-Khoden), default=1\n\t\tIt has no effect for other data formats.\n");
		mexPrintf("\t[NE, NG, NS] are the number of the experiment, the series and the sweep, resp. for sweep selection in HEKA/PatchMaster files. (0 indicates all)\n");
		mexPrintf("\t\t examples: [1,2,3] the 3rd sweep from the 2nd series of experiment 1; [1,3,0] selects all sweeps from experiment=1, series=3. \n\n");
		mexPrintf("   Output:\n\ts\tsignal data, each column is one channel\n");
		mexPrintf("\tHDR\theader structure\n\n");
#endif
		return; 
	}

/*
 	improve checks for input arguments
*/
	/* process input arguments */
	for (k = 0; k < nrhs; k++) {	
		arg = prhs[k];
		if (mxIsEmpty(arg) && (k>0)) {
#ifdef DEBUG		
			mexPrintf("arg[%i] Empty\n",k);
#endif
		}
		else if ((k==0) && mxIsCell(arg) && mxGetNumberOfElements(arg)==1 && mxGetCell(arg,0) && mxIsChar(mxGetCell(arg,0))) {
			FileName = mxArrayToString(mxGetCell(arg,0));
#ifdef DEBUG		
			mexPrintf("arg[%i] IsCell\n",k);
#endif
		}
		else if ((k==0) && mxIsStruct(arg)) {
			FileName = mxArrayToString(mxGetField(prhs[k],0,"FileName"));
#ifdef DEBUG		
			mexPrintf("arg[%i] IsStruct\n",k);
#endif
		}
#ifdef CHOLMOD_H
		else if ((k==1) && mxIsSparse(arg)) {
			rr = sputil_get_sparse(arg,&RR,&dummy,0);
		}
#endif 
		else if ((k==1) && mxIsNumeric(arg)) {
#ifdef DEBUG		
			mexPrintf("arg[%i] IsNumeric\n",k);
#endif
			ChanList = (double*)mxGetData(prhs[k]);
			NS = mxGetNumberOfElements(prhs[k]);
		}	
		else if (mxIsChar(arg)) {
#ifdef DEBUG		
			mexPrintf("arg[%i]=%s \n",k,mxArrayToString(prhs[k]));
#endif
			if (k==0)			
				FileName = mxArrayToString(prhs[k]);
			else if (!strcmp(mxArrayToString(prhs[k]), "CNT32"))
				; // obsolete - supported for backwards compatibility
			else if (!strcmp(mxArrayToString(prhs[k]), "OVERFLOWDETECTION:ON"))
				FlagOverflowDetection = 1;
			else if (!strcmp(mxArrayToString(prhs[k]), "OVERFLOWDETECTION:OFF"))
				FlagOverflowDetection = 0;
			else if (!strcmp(mxArrayToString(prhs[k]), "UCAL:ON")) 
				FlagUCAL = 1;
			else if (!strcmp(mxArrayToString(prhs[k]), "UCAL:OFF"))
				FlagUCAL = 0;
//			else if (!strcmp(mxArrayToString(prhs[k]),"OUTPUT:SINGLE"))
//				FlagMXclass = mxSINGLE_CLASS;
			else if (!strncmp(mxArrayToString(prhs[k]),"TARGETSEGMENT:",14))
				TARGETSEGMENT = atoi(mxArrayToString(prhs[k])+14);
			else if (!strcasecmp(mxArrayToString(prhs[k]), "SWEEP") && (prhs[k+1] != NULL) && mxIsNumeric(prhs[k+1]))
				argSweepSel = ++k;
		}
		else {
#ifndef mexSOPEN
			mexPrintf("mexSLOAD: argument #%i is invalid.",k+1);	
			mexErrMsgTxt("mexSLOAD failes because of unknown parameter\n");	
#else
			mexPrintf("mexSOPEN: argument #%i is invalid.",k+1);	
			mexErrMsgTxt("mexSOPEN fails because of unknown parameter\n");	
#endif
		}
	}

	if (VERBOSE_LEVEL>7) 
		mexPrintf("110: input arguments checked\n");

	hdr = constructHDR(0,0);

#ifdef __LIBBIOSIG2_H__

	unsigned flags = (!!FlagOverflowDetection)*BIOSIG_FLAG_OVERFLOWDETECTION + (!!FlagUCAL)*BIOSIG_FLAG_UCAL;
#ifdef CHOLMOD_H
	flags += (rr!=NULL)*BIOSIG_FLAG_ROW_BASED_CHANNELS;
#else
	biosig_reset_flag(hdr, BIOSIG_FLAG_ROW_BASED_CHANNELS);
#endif
	biosig_set_flag(hdr, flags);

	biosig_set_targetsegment(hdr, TARGETSEGMENT);

	// sweep selection for Heka format
	if (argSweepSel>0) {
		double *SZ     = (double*) mxGetData(prhs[argSweepSel]);
		k = 0;
		while (k < mxGetNumberOfElements(prhs[argSweepSel]) && k < 5) {
			biosig_set_segment_selection(hdr, k+1, (uint32_t)SZ[k]);
			k++;
		}
	}

#else //__LIBBIOSIG2_H__


	hdr->FLAG.OVERFLOWDETECTION = FlagOverflowDetection; 
	hdr->FLAG.UCAL = FlagUCAL;
#ifdef CHOLMOD_H
	hdr->FLAG.ROW_BASED_CHANNELS = (rr!=NULL); 
#else 	
	hdr->FLAG.ROW_BASED_CHANNELS = 0; 
#endif 
	hdr->FLAG.TARGETSEGMENT = TARGETSEGMENT;

	// sweep selection for Heka format 
	if (argSweepSel>0) { 				
		double *SZ     = (double*) mxGetData(prhs[argSweepSel]);
		k = 0;
		while (k < mxGetNumberOfElements(prhs[argSweepSel]) && k < 5) { 
			hdr->AS.SegSel[k] = (uint32_t)SZ[k];
			k++;
		}
	}


#endif // __LIBBIOSIG2_H__ : TODO: below, nothing is converted to level-2 interface, yet


	if (VERBOSE_LEVEL>7) 
		mexPrintf("120: going to sopen\n");

	hdr = sopen(FileName, "r", hdr);
/*
#ifdef WITH_PDP 
	if (hdr->AS.B4C_ERRNUM) {
		hdr->AS.B4C_ERRNUM = 0;
		sopen_pdp_read(hdr);
	}	
#endif
*/
	if (VERBOSE_LEVEL>7) 
		mexPrintf("121: sopen done\n");

	if ((status=serror2(hdr))) {

		const char* fields[]={"TYPE","VERSION","FileName","FLAG","ErrNum","ErrMsg"};
		HDR = mxCreateStructMatrix(1, 1, 6, fields);
#ifdef __LIBBIOSIG2_H__
		mxSetField(HDR,0,"FileName",mxCreateString(biosig_get_filename(hdr)));
		const char *FileTypeString = GetFileTypeString(biosig_get_filetype(hdr));
		mxSetField(HDR,0,"VERSION",mxCreateDoubleScalar(biosig_get_version(hdr)));
#else
		mxSetField(HDR,0,"FileName",mxCreateString(hdr->FileName));
		const char *FileTypeString = GetFileTypeString(hdr->TYPE);
		mxSetField(HDR,0,"VERSION",mxCreateDoubleScalar(hdr->VERSION));
#endif
		mxArray *errnum = mxCreateNumericMatrix(1,1,mxUINT8_CLASS,mxREAL);
		*(uint8_t*)mxGetData(errnum) = (uint8_t)status;
		mxSetField(HDR,0,"ErrNum",errnum);
		
#ifdef HAVE_OCTAVE
		// handle bug in octave: mxCreateString(NULL) causes segmentation fault
		// Octave 3.2.3 causes a seg-fault in mxCreateString(NULL)
		if (FileTypeString) FileTypeString="\0";
#endif
		mxSetField(HDR,0,"TYPE",mxCreateString(FileTypeString));


		char *msg = (char*)malloc(72+23+strlen(FileName)); // 72: max length of constant text, 23: max length of GetFileTypeString()
		if (msg == NULL) 
			mxSetField(HDR,0,"ErrMsg",mxCreateString("Error mexSLOAD: Cannot open file\n"));
		else {	
		    if (status==B4C_CANNOT_OPEN_FILE)
			sprintf(msg,"Error mexSLOAD: file %s not found.\n",FileName);		/* Flawfinder: ignore *** sufficient memory is allocated above */
		    else if (status==B4C_FORMAT_UNKNOWN)
			sprintf(msg,"Error mexSLOAD: Cannot open file %s - format %s not known.\n",FileName,FileTypeString);	/* Flawfinder: ignore *** sufficient memory is allocated above */
		    else if (status==B4C_FORMAT_UNSUPPORTED)
			sprintf(msg,"Error mexSLOAD: Cannot open file %s - format %s not supported [%s].\n", FileName, FileTypeString, hdr->AS.B4C_ERRMSG);	/* Flawfinder: ignore *** sufficient memory is allocated above */
		    else 	
			sprintf(msg,"Error %i mexSLOAD: Cannot open file %s - format %s not supported [%s].\n", status, FileName, FileTypeString, hdr->AS.B4C_ERRMSG); 	/* Flawfinder: ignore *** sufficient memory is allocated above */
			
		    mxSetField(HDR,0,"ErrMsg",mxCreateString(msg));
		    free(msg);
		}    

	if (VERBOSE_LEVEL>7) 
		mexPrintf("737: abort mexSLOAD - sopen failed\n");

		destructHDR(hdr);

	if (VERBOSE_LEVEL>7) 
		mexPrintf("757: abort mexSLOAD - sopen failed\n");

#ifdef mexSOPEN
		plhs[0] = HDR; 
#else
		plhs[0] = mxCreateDoubleMatrix(0,0, mxREAL);
		plhs[1] = HDR; 
#endif 		 
	if (VERBOSE_LEVEL>7) 
		mexPrintf("777: abort mexSLOAD - sopen failed\n");

		return; 
	}

#ifdef CHOLMOD_H
	RerefCHANNEL(hdr,rr,2);
#endif

	if (hdr->FLAG.OVERFLOWDETECTION != FlagOverflowDetection)
		mexPrintf("Warning mexSLOAD: Overflowdetection not supported in file %s\n",hdr->FileName);
	if (hdr->FLAG.UCAL != FlagUCAL)
		mexPrintf("Warning mexSLOAD: Flag UCAL is %i instead of %i (%s)\n",hdr->FLAG.UCAL,FlagUCAL,hdr->FileName);


	if (VERBOSE_LEVEL>7) 
		fprintf(stderr,"[112] SOPEN-R finished NS=%i %i\n",hdr->NS,NS);

//	convert2to4_eventtable(hdr); 
		
#ifdef CHOLMOD_H
	if (hdr->Calib != NULL) {
		NS = hdr->Calib->ncol;
	}
	else 
#endif
	if ((NS<0) || ((NS==1) && (ChanList[0] == 0.0))) { 	// all channels
		for (k=0, NS=0; k<hdr->NS; ++k) {
			if (hdr->CHANNEL[k].OnOff) NS++; 
		}	
	}		
	else {		
		for (k=0; k<hdr->NS; ++k)
			hdr->CHANNEL[k].OnOff = 0; 	// reset
		for (k=0; k<NS; ++k) {
			int ch = (int)ChanList[k];
			if ((ch < 1) || (ch > hdr->NS)) 
				mexPrintf("Invalid channel number CHAN(%i) = %i!\n",k+1,ch); 
			else 	
				hdr->CHANNEL[ch-1].OnOff = 1;  // set
		}		
	}
	
	if (VERBOSE_LEVEL>7) 
		fprintf(stderr,"[113] NS=%i %i\n",hdr->NS,NS);

#ifndef mexSOPEN
	if (hdr->FLAG.ROW_BASED_CHANNELS)
		plhs[0] = mxCreateDoubleMatrix(NS, hdr->NRec*hdr->SPR, mxREAL);
	else
		plhs[0] = mxCreateDoubleMatrix(hdr->NRec*hdr->SPR, NS, mxREAL);

	count = sread(mxGetPr(plhs[0]), 0, hdr->NRec, hdr);
	hdr->NRec = count; 
#endif
	sclose(hdr);
#ifdef CHOLMOD_H
        if (hdr->Calib && hdr->rerefCHANNEL) {
		hdr->NS = hdr->Calib->ncol; 
                free(hdr->CHANNEL);
                hdr->CHANNEL = hdr->rerefCHANNEL;
                hdr->rerefCHANNEL = NULL; 
                hdr->Calib = NULL; 
        }                
#endif 
	if ((status=serror2(hdr))) return;  

	if (VERBOSE_LEVEL>7) 
		fprintf(stderr,"\n[129] SREAD/SCLOSE on %s successful [%i,%i] [%i,%i] %i.\n",hdr->FileName,(int)hdr->data.size[0],(int)hdr->data.size[1],(int)hdr->NRec,(int)count,(int)NS);


//	hdr2ascii(hdr,stderr,4);	

#ifndef mexSOPEN 

	if (nlhs>1) { 
#endif

		char* mexFileName = (char*)mxMalloc(strlen(hdr->FileName)+1); 

		mxArray *tmp, *tmp2, *Patient, *Manufacturer, *ID, *EVENT, *Filter, *Flag, *FileType;
		uint16_t numfields;
		const char *fnames[] = {"TYPE","VERSION","FileName","T0","tzmin","FILE","Patient",\
		"HeadLen","NS","SPR","NRec","SampleRate", "FLAG", \
		"EVENT","Label","LeadIdCode","PhysDimCode","PhysDim","Filter",\
		"PhysMax","PhysMin","DigMax","DigMin","Transducer","Cal","Off","GDFTYP","TOffset",\
		"LowPass","HighPass","Notch","ELEC","Impedance","fZ","AS","Dur","REC","Manufacturer",NULL};

		for (numfields=0; fnames[numfields++] != NULL; );
		HDR = mxCreateStructMatrix(1, 1, --numfields, fnames);

		mxSetField(HDR,0,"TYPE",mxCreateString(GetFileTypeString(hdr->TYPE)));
		mxSetField(HDR,0,"HeadLen",mxCreateDoubleScalar(hdr->HeadLen));
		mxSetField(HDR,0,"VERSION",mxCreateDoubleScalar(hdr->VERSION));
		mxSetField(HDR,0,"NS",mxCreateDoubleScalar(NS));
		mxSetField(HDR,0,"SPR",mxCreateDoubleScalar(hdr->SPR));
		mxSetField(HDR,0,"NRec",mxCreateDoubleScalar(hdr->NRec));
		mxSetField(HDR,0,"SampleRate",mxCreateDoubleScalar(hdr->SampleRate));
		mxSetField(HDR,0,"Dur",mxCreateDoubleScalar(hdr->SPR/hdr->SampleRate));
		mxSetField(HDR,0,"FileName",mxCreateString(hdr->FileName));
                
		mxSetField(HDR,0,"T0",mxCreateDoubleScalar(ldexp(hdr->T0,-32)));
		mxSetField(HDR,0,"tzmin",mxCreateDoubleScalar(hdr->tzmin));

		/* Channel information */ 
#ifdef CHOLMOD_H
/*
        	if (hdr->Calib == NULL) { // is refering to &RR, do not destroy
		        mxArray *Calib = mxCreateDoubleMatrix(hdr->Calib->nrow, hdr->Calib->ncol, mxREAL);

        	}
*/
#endif
		mxArray *LeadIdCode  = mxCreateDoubleMatrix(1,NS, mxREAL);
		mxArray *PhysDimCode = mxCreateDoubleMatrix(1,NS, mxREAL);
		mxArray *GDFTYP      = mxCreateDoubleMatrix(1,NS, mxREAL);
		mxArray *PhysMax     = mxCreateDoubleMatrix(1,NS, mxREAL);
		mxArray *PhysMin     = mxCreateDoubleMatrix(1,NS, mxREAL);
		mxArray *DigMax      = mxCreateDoubleMatrix(1,NS, mxREAL);
		mxArray *DigMin      = mxCreateDoubleMatrix(1,NS, mxREAL);
		mxArray *Cal         = mxCreateDoubleMatrix(1,NS, mxREAL);
		mxArray *Off         = mxCreateDoubleMatrix(1,NS, mxREAL);
		mxArray *Toffset     = mxCreateDoubleMatrix(1,NS, mxREAL);
		mxArray *ELEC_POS    = mxCreateDoubleMatrix(NS,3, mxREAL);
/*
		mxArray *ELEC_Orient = mxCreateDoubleMatrix(NS,3, mxREAL);
		mxArray *ELEC_Area   = mxCreateDoubleMatrix(NS,1, mxREAL);
*/
		mxArray *LowPass     = mxCreateDoubleMatrix(1,NS, mxREAL);
		mxArray *HighPass    = mxCreateDoubleMatrix(1,NS, mxREAL);
		mxArray *Notch       = mxCreateDoubleMatrix(1,NS, mxREAL);
		mxArray *Impedance   = mxCreateDoubleMatrix(1,NS, mxREAL);
		mxArray *fZ          = mxCreateDoubleMatrix(1,NS, mxREAL);
		mxArray *SPR         = mxCreateDoubleMatrix(1,NS, mxREAL);
		mxArray *Label       = mxCreateCellMatrix(NS,1);
		mxArray *Transducer  = mxCreateCellMatrix(NS,1);
		mxArray *PhysDim1    = mxCreateCellMatrix(NS,1);

		for (k=0,k1=0; k1<NS; ++k) 
		if (hdr->CHANNEL[k].OnOff) {
			*(mxGetPr(LeadIdCode)+k1)	= (double)hdr->CHANNEL[k].LeadIdCode;
			*(mxGetPr(PhysDimCode)+k1)	= (double)hdr->CHANNEL[k].PhysDimCode;
			*(mxGetPr(GDFTYP)+k1)		= (double)hdr->CHANNEL[k].GDFTYP;
			*(mxGetPr(PhysMax)+k1)		= (double)hdr->CHANNEL[k].PhysMax;
			*(mxGetPr(PhysMin)+k1)		= (double)hdr->CHANNEL[k].PhysMin;
			*(mxGetPr(DigMax)+k1)		= (double)hdr->CHANNEL[k].DigMax;
			*(mxGetPr(DigMin)+k1)		= (double)hdr->CHANNEL[k].DigMin;
			*(mxGetPr(Toffset)+k1)		= (double)hdr->CHANNEL[k].TOffset;
			*(mxGetPr(Cal)+k1) 		= (double)hdr->CHANNEL[k].Cal;
			*(mxGetPr(Off)+k1) 		= (double)hdr->CHANNEL[k].Off;
			*(mxGetPr(SPR)+k1) 		= (double)hdr->CHANNEL[k].SPR;
			*(mxGetPr(LowPass)+k1) 		= (double)hdr->CHANNEL[k].LowPass;
			*(mxGetPr(HighPass)+k1) 	= (double)hdr->CHANNEL[k].HighPass;
			*(mxGetPr(Notch)+k1) 		= (double)hdr->CHANNEL[k].Notch;
			*(mxGetPr(Impedance)+k1)	= (double)hdr->CHANNEL[k].Impedance;
			*(mxGetPr(fZ)+k1)		= (double)hdr->CHANNEL[k].fZ;
			*(mxGetPr(ELEC_POS)+k1)    	= (double)hdr->CHANNEL[k].XYZ[0];
			*(mxGetPr(ELEC_POS)+k1+NS)	= (double)hdr->CHANNEL[k].XYZ[1];
			*(mxGetPr(ELEC_POS)+k1+NS*2)	= (double)hdr->CHANNEL[k].XYZ[2];
/*
			*(mxGetPr(ELEC_Orient)+k1)	= (double)hdr->CHANNEL[k].Orientation[0];
			*(mxGetPr(ELEC_Orient)+k1+NS)	= (double)hdr->CHANNEL[k].Orientation[1];
			*(mxGetPr(ELEC_Orient)+k1+NS*2)	= (double)hdr->CHANNEL[k].Orientation[2];
			*(mxGetPr(ELEC_Area)+k1)	= (double)hdr->CHANNEL[k].Area;
*/
			mxSetCell(Label,k1,mxCreateString(hdr->CHANNEL[k].Label));
			mxSetCell(Transducer,k1,mxCreateString(hdr->CHANNEL[k].Transducer));
			
			mxSetCell(PhysDim1,k1,mxCreateString(PhysDim3(hdr->CHANNEL[k].PhysDimCode)));
			k1++;
		} 

		mxSetField(HDR,0,"LeadIdCode",LeadIdCode);
		mxSetField(HDR,0,"PhysDimCode",PhysDimCode);
		mxSetField(HDR,0,"GDFTYP",GDFTYP);
		mxSetField(HDR,0,"PhysMax",PhysMax);
		mxSetField(HDR,0,"PhysMin",PhysMin);
		mxSetField(HDR,0,"DigMax",DigMax);
		mxSetField(HDR,0,"DigMin",DigMin);
		mxSetField(HDR,0,"TOffset",Toffset);
		mxSetField(HDR,0,"Cal",Cal);
		mxSetField(HDR,0,"Off",Off);
		mxSetField(HDR,0,"Impedance",Impedance);
		mxSetField(HDR,0,"fZ",fZ);
		mxSetField(HDR,0,"Off",Off);
		mxSetField(HDR,0,"PhysDim",PhysDim1);
		mxSetField(HDR,0,"Transducer",Transducer);
		mxSetField(HDR,0,"Label",Label);

		const char* field[] = {"XYZ","Orientation","Area","GND","REF",NULL};
		for (numfields=0; field[numfields++] != 0; );
		tmp = mxCreateStructMatrix(1, 1, --numfields, field);
		mxSetField(tmp,0,"XYZ",ELEC_POS);
/*
		mxSetField(tmp,0,"Orientation",ELEC_Orient);
		mxSetField(tmp,0,"Area",ELEC_Area);
*/
		mxSetField(HDR,0,"ELEC",tmp);

		const char* field2[] = {"SPR",NULL};
		for (numfields=0; field2[numfields++] != 0; );
		tmp2 = mxCreateStructMatrix(1, 1, --numfields, field2);
		mxSetField(tmp2,0,"SPR",SPR);
		if (hdr->AS.bci2000!=NULL) {
			mxAddField(tmp2, "BCI2000");
			mxSetField(tmp2,0,"BCI2000",mxCreateString(hdr->AS.bci2000));
		}
		if (hdr->TYPE==Sigma) {	
			mxAddField(tmp2, "H1");
			mxSetField(tmp2,0,"H1",mxCreateString((char*)hdr->AS.Header));
		}	
		mxSetField(HDR,0,"AS",tmp2);
				
		/* FLAG */
		const char* field3[] = {"UCAL","OVERFLOWDETECTION","ROW_BASED_CHANNELS",NULL};
		for (numfields=0; field3[numfields++] != 0; );
		Flag = mxCreateStructMatrix(1, 1, --numfields, field3);
#ifdef MX_API_VER
//#if 1
                // Matlab, Octave 3.6.1 
       		mxSetField(Flag,0,"UCAL",mxCreateLogicalScalar(hdr->FLAG.UCAL));
        	mxSetField(Flag,0,"OVERFLOWDETECTION",mxCreateLogicalScalar(hdr->FLAG.OVERFLOWDETECTION));
        	mxSetField(Flag,0,"ROW_BASED_CHANNELS",mxCreateLogicalScalar(hdr->FLAG.ROW_BASED_CHANNELS));
#else 
                // mxCreateLogicalScalar are not included in Octave 3.0 
	        mxSetField(Flag,0,"UCAL",mxCreateDoubleScalar(hdr->FLAG.UCAL));
       		mxSetField(Flag,0,"OVERFLOWDETECTION",mxCreateDoubleScalar(hdr->FLAG.OVERFLOWDETECTION));
       		mxSetField(Flag,0,"ROW_BASED_CHANNELS",mxCreateDoubleScalar(hdr->FLAG.ROW_BASED_CHANNELS));
#endif
		mxSetField(HDR,0,"FLAG",Flag);

		/* Filter */ 
		const char *filter_fields[] = {"HighPass","LowPass","Notch",NULL};
		for (numfields=0; filter_fields[numfields++] != 0; );
		Filter = mxCreateStructMatrix(1, 1, --numfields, filter_fields);
		mxSetField(Filter,0,"LowPass",LowPass);
		mxSetField(Filter,0,"HighPass",HighPass);
		mxSetField(Filter,0,"Notch",Notch);
		mxSetField(HDR,0,"Filter",Filter);

		/* annotation, marker, event table */
		const char *event_fields[] = {"SampleRate","TYP","POS","DUR","CHN","Desc",NULL};
		
		if (hdr->EVENT.DUR == NULL)
			EVENT = mxCreateStructMatrix(1, 1, 3, event_fields);
		else {	
			EVENT = mxCreateStructMatrix(1, 1, 5, event_fields);
			mxArray *DUR = mxCreateDoubleMatrix(hdr->EVENT.N,1, mxREAL);
			mxArray *CHN = mxCreateDoubleMatrix(hdr->EVENT.N,1, mxREAL);
			for (k=0; k<hdr->EVENT.N; ++k) {
				*(mxGetPr(DUR)+k) = (double)hdr->EVENT.DUR[k];
				*(mxGetPr(CHN)+k) = (double)hdr->EVENT.CHN[k];  // channels use a 1-based index, 0 indicates all channels
			} 
			mxSetField(EVENT,0,"DUR",DUR);
			mxSetField(EVENT,0,"CHN",CHN);
		}

		if (hdr->EVENT.CodeDesc != NULL) {
			mxAddField(EVENT, "CodeDesc");
			mxArray *CodeDesc = mxCreateCellMatrix(hdr->EVENT.LenCodeDesc-1,1);
			for (k=1; k < hdr->EVENT.LenCodeDesc; ++k) {
				mxSetCell(CodeDesc,k-1,mxCreateString(hdr->EVENT.CodeDesc[k]));
			} 
			mxSetField(EVENT,0,"CodeDesc",CodeDesc);
		}	

		mxArray *TYP = mxCreateDoubleMatrix(hdr->EVENT.N,1, mxREAL);
		mxArray *POS = mxCreateDoubleMatrix(hdr->EVENT.N,1, mxREAL);

		for (k=0; k<hdr->EVENT.N; ++k) {
			*(mxGetPr(TYP)+k) = (double)hdr->EVENT.TYP[k];
			*(mxGetPr(POS)+k) = (double)hdr->EVENT.POS[k]+1;   // conversion from 0-based to 1-based indexing 
		} 
		mxSetField(EVENT,0,"TYP",TYP);
		mxSetField(EVENT,0,"POS",POS);

#if (BIOSIG_VERSION >= 10500)
		if (hdr->EVENT.TimeStamp) {
			mxArray *TimeStamp = mxCreateDoubleMatrix(hdr->EVENT.N,1, mxREAL);
			for (k=0; k<hdr->EVENT.N; ++k) {
				*(mxGetPr(TimeStamp)+k) = ldexp(hdr->EVENT.TimeStamp[k],-32);
			} 
			mxAddField(EVENT, "TimeStamp");
			mxSetField(EVENT,0,"TimeStamp",TimeStamp);
		}	
#endif
		mxSetField(EVENT,0,"SampleRate",mxCreateDoubleScalar(hdr->EVENT.SampleRate));
		mxSetField(HDR,0,"EVENT",EVENT);

		/* Record identification */ 
		const char *ID_fields[] = {"Recording","Technician","Hospital","Equipment","IPaddr",NULL};
		for (numfields=0; ID_fields[numfields++] != 0; );
		ID = mxCreateStructMatrix(1, 1, --numfields, ID_fields);
		mxSetField(ID,0,"Recording",mxCreateString(hdr->ID.Recording));
		mxSetField(ID,0,"Technician",mxCreateString(hdr->ID.Technician));
		mxSetField(ID,0,"Hospital",mxCreateString(hdr->ID.Hospital));
		mxSetField(ID,0,"Equipment",mxCreateString((char*)&hdr->ID.Equipment));
		int len = 4; 
		uint8_t IPv6=0;
		for (k=4; k<16; k++) IPv6 |= hdr->IPaddr[k];
		if (IPv6) len=16; 
		mxArray *IPaddr = mxCreateNumericMatrix(1,len,mxUINT8_CLASS,mxREAL);
		memcpy(mxGetData(IPaddr),hdr->IPaddr,len);
		mxSetField(ID,0,"IPaddr",IPaddr); 
		mxSetField(HDR,0,"REC",ID);

		/* Patient Information */ 
		const char *patient_fields[] = {"Sex","Handedness","Id","Name","Weight","Height","Birthday",NULL};
		for (numfields=0; patient_fields[numfields++] != 0; );
		Patient = mxCreateStructMatrix(1, 1, --numfields, patient_fields);
		const char *strarray[1];
#ifdef __LIBBIOSIG2_H__
		strarray[0] = biosig_get_patient_name(hdr);
		if (strarray[0]) {
			mxSetField(Patient,0,"Name",mxCreateCharMatrixFromStrings(1,strarray));
		}	
		strarray[0] = biosig_get_patient_id(hdr);
		if (strarray[0]) {
			mxSetField(Patient,0,"Id",mxCreateCharMatrixFromStrings(1,strarray));
		}	
#else
		strarray[0] = hdr->Patient.Name;
		if (strarray[0]) {
			mxSetField(Patient,0,"Name",mxCreateCharMatrixFromStrings(1,strarray));
		}
		strarray[0] = hdr->Patient.Id;
		if (strarray[0]) {
			mxSetField(Patient,0,"Id",mxCreateCharMatrixFromStrings(1,strarray));
		}
#endif
		mxSetField(Patient,0,"Handedness",mxCreateDoubleScalar(hdr->Patient.Handedness));

		mxSetField(Patient,0,"Sex",mxCreateDoubleScalar(hdr->Patient.Sex));
		mxSetField(Patient,0,"Weight",mxCreateDoubleScalar((double)hdr->Patient.Weight));
		mxSetField(Patient,0,"Height",mxCreateDoubleScalar((double)hdr->Patient.Height));
		mxSetField(Patient,0,"Birthday",mxCreateDoubleScalar(ldexp(hdr->Patient.Birthday,-32)));

		double d;
		if (hdr->Patient.Weight==0)		d = NAN;	// not-a-number		
		else if (hdr->Patient.Weight==255)	d = INFINITY;	// Overflow
		else					d = (double)hdr->Patient.Weight;
		mxSetField(Patient,0,"Weight",mxCreateDoubleScalar(d));
			
		if (hdr->Patient.Height==0)		d = NAN;	// not-a-number		
		else if (hdr->Patient.Height==255)	d = INFINITY;	// Overflow
		else					d = (double)hdr->Patient.Height;
		mxSetField(Patient,0,"Height",mxCreateDoubleScalar(d));
	
		/* Manufacturer Information */ 
		const char *manufacturer_fields[] = {"Name","Model","Version","SerialNumber",NULL};
		for (numfields=0; manufacturer_fields[numfields++] != 0; );
		Manufacturer = mxCreateStructMatrix(1, 1, --numfields, manufacturer_fields);

#ifdef __LIBBIOSIG2_H__
		strarray[0] = biosig_get_manufacturer_name(hdr);
		if (strarray[0]) {
			mxSetField(Manufacturer,0,"Name",mxCreateCharMatrixFromStrings(1,strarray));
		}	
		strarray[0] = biosig_get_manufacturer_model(hdr);
		if (strarray[0]) {
			biosig_get_manufacturer_model(hdr);
			mxSetField(Manufacturer,0,"Model",mxCreateCharMatrixFromStrings(1,strarray));
		}	
		strarray[0] = biosig_get_manufacturer_version(hdr);
		if (strarray[0]) {
			biosig_get_manufacturer_version(hdr);
			mxSetField(Manufacturer,0,"Version",mxCreateCharMatrixFromStrings(1,strarray));
		}	
		strarray[0] = biosig_get_manufacturer_serial_number(hdr);
		if (strarray[0]) {
			mxSetField(Manufacturer,0,"SerialNumber",mxCreateCharMatrixFromStrings(1,strarray));
		}
#else
		strarray[0] = hdr->ID.Manufacturer.Name;
		if (strarray[0]) {
			mxSetField(Manufacturer,0,"Name",mxCreateCharMatrixFromStrings(1,strarray));
		}
		strarray[0] = hdr->ID.Manufacturer.Model;
		if (strarray[0]) {
			mxSetField(Manufacturer,0,"Model",mxCreateCharMatrixFromStrings(1,strarray));
		}
		strarray[0] = hdr->ID.Manufacturer.Version;
		if (strarray[0]) {
			mxSetField(Manufacturer,0,"Version",mxCreateCharMatrixFromStrings(1,strarray));
		}
		strarray[0] = hdr->ID.Manufacturer.SerialNumber;
		if (strarray[0]) {
			mxSetField(Manufacturer,0,"SerialNumber",mxCreateCharMatrixFromStrings(1,strarray));
		}
#endif
		mxSetField(HDR,0,"Manufacturer",Manufacturer);


	if (VERBOSE_LEVEL>7) 
		fprintf(stdout,"[148] going for SCLOSE\n");

		mxSetField(HDR,0,"Patient",Patient);

#ifndef mexSOPEN
		plhs[1] = HDR; 
	}
#else
	plhs[0] = HDR; 
#endif

	if (VERBOSE_LEVEL>7) fprintf(stdout,"[151] going for SCLOSE\n");
#ifdef CHOLMOD_H
	hdr->Calib = NULL; // is refering to &RR, do not destroy
#endif
	if (VERBOSE_LEVEL>7) fprintf(stdout,"[156] SCLOSE finished\n");
	destructHDR(hdr);
	hdr = NULL; 
	if (VERBOSE_LEVEL>7) fprintf(stdout,"[157] SCLOSE finished\n");
};
Exemplo n.º 7
0
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
  unsigned char **HH, **GG;
  mwIndex ii, jj, *ir, *jc, rdep, tmp, d;
  double *sr1, *sr2, *g;
  mwSize N, M, K, nz;
  mwIndex i, j, k, kk, *irs1, *jcs1, *irs2, *jcs2;

  /* Check for proper number of arguments */
  if (nrhs != 1) {
    mexErrMsgTxt("h2g requires one input arguments.");
  } else if (nlhs != 2) {
    mexErrMsgTxt("h2g requires two output arguments.");
  } else if (!mxIsSparse(H_IN)) {
    mexErrMsgTxt("h2g requires sparse H matrix.");
  }

  /* read sparse matrix H */
  sr1 = mxGetPr(H_IN);
  irs1 = mxGetIr(H_IN);  /* row */
  jcs1 = mxGetJc(H_IN);  /* column */
  nz = mxGetNzmax(H_IN); /* number of nonzero elements (they are ones)*/
  M = mxGetM(H_IN);
  N = mxGetN(H_IN);

  /* create working array HH[row][column]*/
  HH = (unsigned char **)mxMalloc(M * sizeof(unsigned char *));
  for (i = 0; i < M; i++) {
    HH[i] = (unsigned char *)mxMalloc(N * sizeof(unsigned char));
  }
  for (i = 0; i < M; i++)
    for (j = 0; j < N; j++)
      HH[i][j] = 0; /* initialize all to zero */

  k = 0;
  for (j = 0; j < N; j++) {
    for (i = 0; i < (jcs1[j + 1] - jcs1[j]); i++) {
      ii = irs1[k];       /* index in column j*/
      HH[ii][j] = sr1[k]; /* put  nonzeros */
      k++;
    }
  }

  /* invert HH matrix here */
  /* row and column indices */
  ir = (mwIndex *)mxMalloc(M * sizeof(mwIndex));
  jc = (mwIndex *)mxMalloc(N * sizeof(mwIndex));
  for (i = 0; i < M; i++)
    ir[i] = i;
  for (j = 0; j < N; j++)
    jc[j] = j;

  /* perform Gaussian elimination on H, store reodering operations */
  rdep = 0; /* number of dependent rows in H*/
  d = 0;    /* current diagonal element */

  while ((d + rdep) < M) { /* cycle through independent rows of H */

    j = d; /* current column index along row ir[d] */
    while ((HH[ir[d]][jc[j]] == 0) && (j < (N - 1)))
      j++;                  /* find first nonzero element in row i */
    if (HH[ir[d]][jc[j]]) { /* found nonzero element. It is "1" in GF2 */

      /* swap columns */
      tmp = jc[d];
      jc[d] = jc[j];
      jc[j] = tmp;

      /* eliminate current column using row operations */
      for (ii = 0; ii < M; ii++)
        if (HH[ir[ii]][jc[d]] && (ir[ii] != ir[d]))
          for (jj = d; jj < N; jj++)
            HH[ir[ii]][jc[jj]] = (HH[ir[ii]][jc[jj]] + HH[ir[d]][jc[jj]]) % 2;
    } else {  /* all zeros -  need to delete this row and update indices */
      rdep++; /* increase number of dependent rows */
      tmp = ir[d];
      ir[d] = ir[M - rdep];
      ir[M - rdep] = tmp;
      d--; /* no diagonal element is found */
    }
    d++; /* increase the number of diagonal elements */
  }      /*while i+rdep*/
         /* done inverting HH */

  K = N - M + rdep; /* true K */

  /* create G matrix  G = [A'| I] if H = [I|A]*/
  GG = (unsigned char **)mxMalloc(K * sizeof(unsigned char *));
  for (i = 0; i < K; i++) {
    GG[i] = (unsigned char *)mxMalloc(N * sizeof(unsigned char));
  }
  for (i = 0; i < K; i++)
    for (j = 0; j < (N - K); j++) {
      tmp = (N - K + i);
      GG[i][j] = HH[ir[j]][jc[tmp]];
    }

  for (i = 0; i < K; i++)
    for (j = (N - K); j < N; j++)
      if (i == (j - N + K)) /* diagonal */
        GG[i][j] = 1;
      else
        GG[i][j] = 0;

  /* NOTE, it is very inefficient way to store G. Change to taste!*/
  G_OUT = mxCreateDoubleMatrix(K, N, mxREAL);
  /* Assign pointers to the output matrix */
  g = mxGetPr(G_OUT);
  for (i = 0; i < K; i++)
    for (j = 0; j < N; j++)
      g[i + j * K] = GG[i][j];

  H_OUT = mxCreateSparse(M, N, nz, mxREAL);
  sr2 = mxGetPr(H_OUT);
  irs2 = mxGetIr(H_OUT); /* row */
  jcs2 = mxGetJc(H_OUT); /* column */
  /* Write H_OUT swapping columns according to jc */
  k = 0;
  for (j = 0; (j < N); j++) {
    jcs2[j] = k;
    tmp = jcs1[jc[j] + 1] - jcs1[jc[j]];
    for (i = 0; i < tmp; i++) {
      kk = jcs1[jc[j]] + i;
      sr2[k] = sr1[kk];
      irs2[k] = irs1[kk];
      k++;
    }
  }
  jcs2[N] = k;

  /* free the memory */
  for (j = 0; j < M; j++) {
    mxFree(HH[j]);
  }
  mxFree(HH);
  mxFree(ir);
  mxFree(jc);
  for (i = 0; i < K; i++) {
    mxFree(GG[i]);
  }
  mxFree(GG);
  return;
}
//=========================================================================
//=========================================================================
void initialize_unique_objects(unsigned char *js,mxArray *plhs[], struct sdata *slog){
    //
    //  This code will initialize unique objects (structures) with keys, 
    //  based on already having identified unique objects earlier.
    //
    //  This function populates
    //  -----------------------
    //  objects : cell array of empty structs with fields
    
    
    int n_unique_objects = slog->obj__n_unique_objects;
    
    if (n_unique_objects == 0){
        return;
    }
    
    int *d1 = get_int_field_by_number(plhs[0],E_d1);
    
    mxArray *object_info = plhs[0];
    
    int *child_count_object = get_int_field_by_number(object_info,E_obj__child_count_object);    
    int *unique_object_first_md_indices = get_int_field_by_number(object_info,E_obj__unique_object_first_md_indices);
    
    int max_keys_in_object = slog->obj__max_keys_in_object;
    
    if (max_keys_in_object == 0){
        //We have at least one objects, but none of the objects have keys
        //Create a single unique object with no fields ...
        mxArray *all_objects = mxCreateCellMatrix(1,1);
        mxArray *s = mxCreateStructMatrix(1,0,0,0);
        mxSetCell(all_objects, 0, s);
        mxSetFieldByNumber(object_info,0,E_obj__objects,all_objects);
        return;
    }
    
    //TODO: Define this here ...
    int *object_ids = get_int_field_by_number(object_info,E_obj__object_ids);
     
    mxArray *key_info = plhs[0];
    mxArray *temp_key_p = mxGetFieldByNumber(key_info,0,E_key__key_p);
    
    unsigned char **key_p = (unsigned char **)mxGetData(temp_key_p);
    
    
    int *key_sizes = get_int_field_by_number(key_info,E_key__key_sizes);
    int *next_sibling_index_key = get_int_field_by_number(key_info,E_key__next_sibling_index_key);
    
    //Note, Matlab does a deep copy of this field, so we are only
    //allocating a temporary array, note the final values.
    const char **fieldnames = mxMalloc(max_keys_in_object*sizeof(char *));
    
    //This is the output, stored in our output structure as "objects"
    mxArray *all_objects = mxCreateCellMatrix(1, n_unique_objects);
     
    mxArray *s;
    
    unsigned char *cur_key_p;
    int cur_key_md_index;
    int cur_key_data_index;
    int cur_key_size;
    int temp_key_index;
    
    int cur_object_md_index;
    int cur_object_data_index;
    int n_keys_in_object;
    
    //  For each unique object, get an example object and grab the fields
    //  of that object.
    
    for (int iObj = 0; iObj < n_unique_objects; iObj++){   
        cur_object_md_index = unique_object_first_md_indices[iObj];
        cur_object_data_index = d1[cur_object_md_index]; 
        n_keys_in_object = child_count_object[cur_object_data_index];

        cur_key_md_index = cur_object_md_index + 1;
        cur_key_data_index = d1[cur_key_md_index];
                
        for (int iKey = 0; iKey < n_keys_in_object; iKey++){
            cur_key_p = key_p[cur_key_data_index];
            cur_key_size = key_sizes[cur_key_data_index];
                        
            //JAH Notes 2018-09
            //1) This is modifying the original the JSON string
            //   which should be documented ...
            //      - we could fix this by writing the " back in
            //      - "my_string" => "my_string\0 => "my_string"
            //      - Matlab is deep copying the strings in
            //        mxCreateStructMatrix
            //2) We are not parsing for UTF-8, Matlab only supports
            //   ASCII for fields, this should be documented
            
            //At a minimum, we'll zero out the key to specify length
            //for Matlab. Matlab takes in an array of pointers to 
            //null-terminated strings rather than allowing us to specify
            //the size. So here we add null termination into the string.
            //Note that we are always zeroing a terminating quote symbol.
            *(cur_key_p + cur_key_size) = 0;
            
            fieldnames[iKey] = cur_key_p;
            
            //TODO: It is not obvious how the next sibling behaves at the
            //end - comment on this here ...
            cur_key_md_index = next_sibling_index_key[cur_key_data_index];
            cur_key_data_index = d1[cur_key_md_index];            
        }
        
        //We'll initialize as empty here, because we don't get much of 
        //an advantage of preinitializing if we are going to chop this up later
        //Initialing to zero still logs the field names
        //Any advantage of 1,0 vs 0,0?, vs even 1,1?
        //1,1 might be good if we only have 1 example, then we could
        //just use it later ... - this would require counting how many
        //objects take on this value ...
        s = mxCreateStructMatrix(1,0,n_keys_in_object,fieldnames);
        mxSetCell(all_objects, iObj, s);
    }
    
    mxFree(fieldnames);
    mxSetFieldByNumber(object_info,0,E_obj__objects,all_objects);
    
}
//=========================================================================
void populate_object_flags(unsigned char *js,mxArray *plhs[], struct sdata *slog){
    //
    //  For each object, identify which "unique" object it belongs to and
    //  which index it has in that object.
    //
    //  Populates (into object_info structure)
    //  ---------------------------------------
    //  max_keys_in_object
    //  n_uniqe_objects: scalar 
    //  object_ids: array
    //  unique_object_first_md_indices: array
    //
    
    mxArray *object_info = plhs[0]; //mxGetField(plhs[0],0,"object_info");
    
    //TODO: Change this to numeric ...
    int n_objects = get_field_length2(object_info,"obj__next_sibling_index_object");
    
    if (n_objects == 0){
        slog->obj__n_unique_objects = 0;
        setStructField2(object_info,0,mxINT32_CLASS,0,E_obj__object_ids); 
        return;
    }
    
    
    //Main data info
    //-------------------------------------
    uint8_t *types = get_u8_field_by_number(plhs[0],E_types);
    int *d1 = get_int_field_by_number(plhs[0],E_d1);
    
    //TODO: Change this to numeric ...
    mwSize n_entries = get_field_length(plhs,"d1");

    //Information needed for this processing
    //---------------------------------------------------------------------
    //Object related
    uint8_t *object_depths = get_u8_field_by_number(object_info,E_obj__object_depths);
    int *child_count_object = get_int_field_by_number(object_info,E_obj__child_count_object);
    int *next_sibling_index_object = get_int_field_by_number(object_info,E_obj__next_sibling_index_object);
    int *n_objects_at_depth = slog->obj__n_objects_at_depth;
    
    mwSize n_depths = MAX_DEPTH_ARRAY_LENGTH; //get_field_length2(object_info,"n_objects_at_depth");
    
    //Some initial - meta setup
    //---------------------------------------------------------------------
    int *process_order = mxMalloc(n_objects*sizeof(int));
    populateProcessingOrder(process_order, types, n_entries, TYPE_OBJECT, n_objects_at_depth, n_depths, object_depths);
    
    //What is the max # of keys per object?
    int max_children = 0;
    for (int iObject = 0; iObject < n_objects; iObject++){
        if (child_count_object[iObject] > max_children){
            max_children = child_count_object[iObject];
        }
    }
    slog->obj__max_keys_in_object = max_children;
    
    if (max_children == 0){
        //So we only have an empty object
        int *unique_object_first_md_indices = mxMalloc(1*sizeof(int));
        unique_object_first_md_indices[0] = process_order[0];
        int *object_ids = mxCalloc(n_objects,sizeof(int));
        
    	setStructField2(object_info,unique_object_first_md_indices,
                mxINT32_CLASS,1,E_obj__unique_object_first_md_indices);
        setStructField2(object_info,object_ids,mxINT32_CLASS,n_objects,E_obj__object_ids); 
        slog->obj__n_unique_objects = 1;
        return;
    }

    //Key related
    //---------------------------------
    mxArray *key_info = plhs[0];
    mxArray *temp_key_p = mxGetFieldByNumber(key_info,0,E_key__key_p);
    unsigned char **key_p = (unsigned char **)mxGetData(temp_key_p);
    int *key_sizes = get_int_field_by_number(key_info,E_key__key_sizes);
    int *next_sibling_index_key = get_int_field_by_number(key_info,E_key__next_sibling_index_key); 

    //These are our outputs
    //---------------------------------------------------------------------
    //Which unique object, each object entry belongs to
    int *object_ids = mxMalloc(n_objects*sizeof(int));
    
    int n_unique_allocated;
    if (n_objects > N_INITIAL_UNIQUE_OBJECTS){
        n_unique_allocated = N_INITIAL_UNIQUE_OBJECTS;
    }else{
        n_unique_allocated = n_objects;
    }
        
    //We need this so that later we can go back and parse the keys
    //TODO: We could technically parse the keys right away ...
    int *unique_object_first_md_indices = mxMalloc(n_unique_allocated*sizeof(int));
    //---------------------------------------------------------------------
    
    //Variables for the loop 
    int cur_object_id = -1; //-1, allows incrementing into current value

    //po - process order
    int cur_po_index = 0; 
    int cur_object_md_index;
    int cur_object_data_index;
    
    int cur_key_data_index;
    int temp_key_md_index;
    int n_keys_current_object;
    
    int *object_key_sizes = mxMalloc(max_children*sizeof(int));
    unsigned char **object_key_pointers = mxMalloc(max_children*sizeof(unsigned char *));
    
    
    int last_obj_iter = -1;
    
    bool done = false;
    bool diff_object;
    
    //  Main Loop
    //---------------------------------------------------------------------
    while (!done){
        
        //Creation of a Reference Object
        //-----------------------------------------------------------------
        // - other objects will be compared to this object
        cur_object_md_index = process_order[cur_po_index];
        cur_object_data_index = RETRIEVE_DATA_INDEX(cur_object_md_index);
        n_keys_current_object = child_count_object[cur_object_data_index];
        
        object_ids[cur_object_data_index] = ++cur_object_id;
        
        //Logging of unique_object_first_data_indices
        //Technically we could post-process this bit ...
        //i.e. after assigning all objects unique ids, run through
        //and populate unique_object_first_data_indices
        if (cur_object_id >= n_unique_allocated){
            n_unique_allocated = 2*n_unique_allocated;
            if (n_unique_allocated > n_objects){
                n_unique_allocated = n_objects;
            }
            unique_object_first_md_indices = mxRealloc(unique_object_first_md_indices,
                    n_unique_allocated*sizeof(int));
        }
        
        unique_object_first_md_indices[cur_object_id] = cur_object_md_index; 


        //-----------------------------------------------------------------
        //Store key information for comparison to other objects ...
        //-----------------------------------------------------------------
        cur_key_data_index = RETRIEVE_DATA_INDEX((cur_object_md_index + 1));
        for (int iKey = 0; iKey < n_keys_current_object; iKey ++){
            object_key_sizes[iKey] = key_sizes[cur_key_data_index];
            object_key_pointers[iKey] = key_p[cur_key_data_index];
            
            temp_key_md_index = next_sibling_index_key[cur_key_data_index];
            cur_key_data_index = RETRIEVE_DATA_INDEX(temp_key_md_index);
        }
        
        //-----------------------------------------------------------------
        //      Loop through the other objects and compare
        //-----------------------------------------------------------------
        diff_object = false;
        while (!diff_object){
            ++cur_po_index;
            if (cur_po_index == n_objects){
                done = true;
                break;
            }
            
            cur_object_md_index = process_order[cur_po_index];
            cur_object_data_index = RETRIEVE_DATA_INDEX(cur_object_md_index);
            
            if (n_keys_current_object == child_count_object[cur_object_data_index]){
                
                //TODO
                //It might be better to combine these two loops
                
                //Here we check if the keys are the same length
                //---------------------------------------------------------
                cur_key_data_index = RETRIEVE_DATA_INDEX((cur_object_md_index + 1));
                for (int iKey = 0; iKey < n_keys_current_object; iKey ++){
                    if (object_key_sizes[iKey] != key_sizes[cur_key_data_index]){
                        diff_object = true;
                        break;
                    }
                    temp_key_md_index = next_sibling_index_key[cur_key_data_index];
                    cur_key_data_index = RETRIEVE_DATA_INDEX(temp_key_md_index);
                }    
                
                //Here we check if the key values are the same
                //---------------------------------------------------------
                if (!diff_object){
                    cur_key_data_index = RETRIEVE_DATA_INDEX((cur_object_md_index + 1));
                    for (int iKey = 0; iKey < n_keys_current_object; iKey ++){
                        
                        if (memcmp(object_key_pointers[iKey],
                                key_p[cur_key_data_index],object_key_sizes[iKey])){
                            diff_object = true;
                            break;
                        };
                        temp_key_md_index = next_sibling_index_key[cur_key_data_index];
                        cur_key_data_index = RETRIEVE_DATA_INDEX(temp_key_md_index);
                    }  
                }
                
                if (!diff_object){
                    object_ids[cur_object_data_index] = cur_object_id;
                }
                
            }else{
                diff_object = true;
            }
        }   
    }
    
    mxFree(object_key_pointers);
    mxFree(object_key_sizes);
    mxFree(process_order);
    
    //TODO: We could truncate these ...
    //TODO: Change to #2 method with enumeration ...
    setStructField2(object_info,unique_object_first_md_indices,
            mxINT32_CLASS,cur_object_id+1,E_obj__unique_object_first_md_indices);    
    setStructField2(object_info,object_ids,
            mxINT32_CLASS,n_objects,E_obj__object_ids); 
    slog->obj__n_unique_objects = cur_object_id+1;
}
/* 
 * mexFunction
 *
 * This is like main for a matlab integration point. When matlab calls the
 * function which is setup to associate with this file, this will be the entry
 * point.
 *
 * int nlhs      - number of LHS arguments (return arguments)
 * mxArray *plhs - an array to fill with these return arguments
 * int nrhs      - number of RHS arguments (function arguments)
 * mxArray *prhs - an array containing these function arguments
 *
 * In our specific case, we are expecting the following input arguments:
 *
 * KTrans        - array of floats [2D, real valued]
 * k_ep          - array of floats [2D, real valued]
 * dt_i          - float
 * Ti            - int
 * dt_j          - float
 * Tj            - int
 * Cpi           - vector of floats [2D, real valued]
 * samplingRate  - float
 * gpuAccelerate - bool
 *
 * and the following output arguments:
 *
 * imgSeq - array of floats [3D, complex valued]
 */
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
  /* Check for the correct number of input arguments */
  if (nrhs != 9) {
    mexPrintf("Wrong number of arguments, expecting ...(kTrans, kEp, t0, samplingRate)\n");
    return;
  } 

  /* Check for the correct number of output arguments */
  if (nlhs != 1) {
    mexPrintf("Wrong number of return values, expecting 1");
    return;
  } 

  /* Extract specific mxArray input structures */
  const mxArray *mx_KTrans = prhs[0];
  const mxArray *mx_k_ep = prhs[1];
  const mxArray *mx_dt_i = prhs[2];
  const mxArray *mx_Ti = prhs[3];
  const mxArray *mx_dt_j = prhs[4];
  const mxArray *mx_Tj = prhs[5];
  const mxArray *mx_Cpi = prhs[6];
  const mxArray *mx_samplingRate = prhs[7];
  const mxArray *mx_gpuAccelerate = prhs[8];

  /* Extract specific input data ptrs */
  float *KTrans = (float *)mxGetPr(mx_KTrans);
  float *k_ep = (float *)mxGetPr(mx_k_ep);
  float dt_i = *(float *)mxGetPr(mx_dt_i);
  int Ti = *(int *)mxGetPr(mx_Ti);
  float dt_j = *(float *)mxGetPr(mx_dt_j);
  int Tj = *(int *)mxGetPr(mx_Tj);
  float *Cpi = (float *)mxGetPr(mx_Cpi);
  float samplingRate = *(float *)mxGetPr(mx_samplingRate);
  bool gpuAccelerate = *(bool *)mxGetPr(mx_gpuAccelerate);

  /* Extract other useful information from input */
  const mwSize *kTransDims = mxGetDimensions(mx_KTrans);

  /* Setup output matrix */
  mwSize ndim = 3;
  mwSize *dims = (mwSize *)mxMalloc(ndim * sizeof(mwSize));
  dims[0] = kTransDims[0]; dims[1] = kTransDims[1]; dims[2] = Tj;
  mxArray *mxImgSeq = mxCreateNumericArray(ndim, dims, mxSINGLE_CLASS, mxCOMPLEX);

  /* Extract specific output data ptrs */
  float *imgSeqR = (float *)mxGetPr(mxImgSeq);
  float *imgSeqI = (float *)mxGetPi(mxImgSeq);

  /* Call the appropriate kernel with the translated data */
  int success;
  if (gpuAccelerate) {
    /* Call the CUDA kernel */
    success = gpuSetupAndConvolve(
        KTrans, 
        k_ep, 
        dt_i, 
        Ti, 
        dt_j, 
        Tj, 
        Cpi, 
        samplingRate, 
        imgSeqR, 
        imgSeqI, 
        dims[0], 
        dims[1]);
  } else {
    /* Call a sequential C version of the kernel */
    success = cSetupAndConvolve(
        KTrans, 
        k_ep, 
        dt_i, 
        Ti, 
        dt_j, 
        Tj, 
        Cpi, 
        samplingRate, 
        imgSeqR, 
        imgSeqI, 
        dims[0], 
        dims[1]);
  }

  /* Check that cuda code completed successfully */
  if (success != 0) {
    mexPrintf("Cuda host encountered a memory error.\n");
  }

  /* Free memory */
  mxFree(dims);

  /* Set output to computed matrix */
  plhs[0] = mxImgSeq;
}
Exemplo n.º 11
0
const char *model_to_matlab_structure(mxArray *plhs[], struct model *model_)
{
	int i;
	int nr_w;
	double *ptr;
	mxArray *return_model, **rhs;
	int out_id = 0;
	int n, w_size;

	rhs = (mxArray **)mxMalloc(sizeof(mxArray *)*NUM_OF_RETURN_FIELD);

	// Parameters
	// for now, only solver_type is needed
	rhs[out_id] = mxCreateDoubleMatrix(1, 1, mxREAL);
	ptr = mxGetPr(rhs[out_id]);
	ptr[0] = model_->param.solver_type;
	out_id++;

	// nr_class
	rhs[out_id] = mxCreateDoubleMatrix(1, 1, mxREAL);
	ptr = mxGetPr(rhs[out_id]);
	ptr[0] = model_->nr_class;
	out_id++;

	if(model_->nr_class==2 && model_->param.solver_type != MCSVM_CS)
		nr_w=1;
	else
		nr_w=model_->nr_class;

	// nr_feature
	rhs[out_id] = mxCreateDoubleMatrix(1, 1, mxREAL);
	ptr = mxGetPr(rhs[out_id]);
	ptr[0] = model_->nr_feature;
	out_id++;

	// bias
	rhs[out_id] = mxCreateDoubleMatrix(1, 1, mxREAL);
	ptr = mxGetPr(rhs[out_id]);
	ptr[0] = model_->bias;
	out_id++;

	if(model_->bias>=0)
		n=model_->nr_feature+1;
	else
		n=model_->nr_feature;

	w_size = n;
	// Label
	if(model_->label)
	{
		rhs[out_id] = mxCreateDoubleMatrix(model_->nr_class, 1, mxREAL);
		ptr = mxGetPr(rhs[out_id]);
		for(i = 0; i < model_->nr_class; i++)
			ptr[i] = model_->label[i];
	}
	else
		rhs[out_id] = mxCreateDoubleMatrix(0, 0, mxREAL);
	out_id++;

	// w
	rhs[out_id] = mxCreateDoubleMatrix(nr_w, w_size, mxREAL);
	ptr = mxGetPr(rhs[out_id]);
	for(i = 0; i < w_size*nr_w; i++)
		ptr[i]=model_->w[i];
	out_id++;

	/* Create a struct matrix contains NUM_OF_RETURN_FIELD fields */
	return_model = mxCreateStructMatrix(1, 1, NUM_OF_RETURN_FIELD, field_names);

	/* Fill struct matrix with input arguments */
	for(i = 0; i < NUM_OF_RETURN_FIELD; i++)
		mxSetField(return_model,0,field_names[i],mxDuplicateArray(rhs[i]));
	/* return */
	plhs[0] = return_model;
	mxFree(rhs);

	return NULL;
}
Exemplo n.º 12
0
void EnforceConnectivity(int* labels, int width, int height, int numSuperpixels,int* nlabels, int* finalNumberOfLabels)
{
    int i,j,k;
    int n,c,count;
    int x,y;
    int ind;
    int label;
    const int dx4[4] = {-1,  0,  1,  0};
	 const int dy4[4] = { 0, -1,  0,  1};
    const int sz = width*height;
    int* xvec = (int*) mxMalloc(sizeof(int)*sz);
	 int* yvec = (int*) mxMalloc(sizeof(int)*sz);
	 const int SUPSZ = sz/numSuperpixels;
	 for( i = 0; i < sz; i++ ) nlabels[i] = -1;
	 int oindex = 0;
	 int adjlabel = 0;//adjacent label
    label = 0;
	 for( j = 0; j < height; j++ )
	 {
		for( k = 0; k < width; k++ )
		{
			if( 0 > nlabels[oindex] )
			{
				nlabels[oindex] = label;
				//--------------------
				// Start a new segment
				//--------------------
				xvec[0] = k;
				yvec[0] = j;
				//-------------------------------------------------------
				// Quickly find an adjacent label for use later if needed
				//-------------------------------------------------------
				{for( n = 0; n < 4; n++ )
				{
					int x = xvec[0] + dx4[n];
					int y = yvec[0] + dy4[n];
					if( (x >= 0 && x < width) && (y >= 0 && y < height) )
					{
						int nindex = y*width + x;
						if(nlabels[nindex] >= 0) adjlabel = nlabels[nindex];
					}
				}}
                
				count = 1;
				for( c = 0; c < count; c++ )
				{
					for( n = 0; n < 4; n++ )
					{
						x = xvec[c] + dx4[n];
						y = yvec[c] + dy4[n];
                        
						if( (x >= 0 && x < width) && (y >= 0 && y < height) )
						{
							int nindex = y*width + x;
                            
							if( 0 > nlabels[nindex] && labels[oindex] == labels[nindex] )
							{
								xvec[count] = x;
								yvec[count] = y;
								nlabels[nindex] = label;
								count++;
							}
						}
                        
					}
				}
				//-------------------------------------------------------
				// If segment size is less then a limit, assign an
				// adjacent label found before, and decrement label count.
				//-------------------------------------------------------
				if(count <= SUPSZ >> 2)
				{
					for( c = 0; c < count; c++ )
					{
                  ind = yvec[c]*width+xvec[c];
						nlabels[ind] = adjlabel;
					}
					label--;
				}
				label++;
			}
			oindex++;
		}
	}
Exemplo n.º 13
0
void PerformSuperpixelSLIC(double* lvec, double* avec, double* bvec, double* kseedsl, double* kseedsa, double* kseedsb, double* kseedsx, double* kseedsy, int width, int height, int numseeds, int* klabels, int STEP, double compactness)
{
    int x1, y1, x2, y2;
	double l, a, b;
	double dist;
	double distxy;
    int itr;
    int n;
    int x,y;
    int i;
    int ind;
    int r,c;
    int k;
    int sz = width*height;
	const int numk = numseeds;
	int offset = STEP;
    
    double* clustersize = (double*) mxMalloc(sizeof(double)*numk);
    double* inv         = (double*) mxMalloc(sizeof(double)*numk);
    double* sigmal      = (double*) mxMalloc(sizeof(double)*numk);
    double* sigmaa      = (double*) mxMalloc(sizeof(double)*numk);
    double* sigmab      = (double*) mxMalloc(sizeof(double)*numk);
    double* sigmax      = (double*) mxMalloc(sizeof(double)*numk);
    double* sigmay      = (double*) mxMalloc(sizeof(double)*numk);
    double* distvec     = (double*) mxMalloc(sizeof(double)*sz);
	double invwt = 1.0/((STEP/compactness)*(STEP/compactness));
    
	for( itr = 0; itr < 10; itr++ )
	{
		for(i = 0; i < sz; i++){distvec[i] = DBL_MAX;}
     
		for( n = 0; n < numk; n++ )
		{
            x1 = kseedsx[n]-offset; if(x1 < 0) x1 = 0;
            y1 = kseedsy[n]-offset; if(y1 < 0) y1 = 0;
            x2 = kseedsx[n]+offset; if(x2 > width)  x2 = width;
            y2 = kseedsy[n]+offset; if(y2 > height) y2 = height;
            
			for( y = y1; y < y2; y++ )
			{
				for( x = x1; x < x2; x++ )
				{
					i = y*width + x;
                    
					l = lvec[i];
					a = avec[i];
					b = bvec[i];
                    
					dist =			(l - kseedsl[n])*(l - kseedsl[n]) +
                                    (a - kseedsa[n])*(a - kseedsa[n]) +
                                    (b - kseedsb[n])*(b - kseedsb[n]);
                    
					distxy =		(x - kseedsx[n])*(x - kseedsx[n]) + (y - kseedsy[n])*(y - kseedsy[n]);
					
					dist += distxy*invwt;
                    
					if(dist < distvec[i])
					{
						distvec[i] = dist;
						klabels[i]  = n;
					}
				}
			}
		}
		//-----------------------------------------------------------------
		// Recalculate the centroid and store in the seed values
		//-----------------------------------------------------------------
        for(k = 0; k < numk; k++)
        {
            sigmal[k] = 0;
            sigmaa[k] = 0;
            sigmab[k] = 0;
            sigmax[k] = 0;
            sigmay[k] = 0;
            clustersize[k] = 0;
        }
        
		ind = 0;
        for( r = 0; r < height; r++ )
        {
            for( c = 0; c < width; c++ )
            {
                if(klabels[ind] >0)
                {
                    sigmal[klabels[ind]] += lvec[ind];
                    sigmaa[klabels[ind]] += avec[ind];
                    sigmab[klabels[ind]] += bvec[ind];
                    sigmax[klabels[ind]] += c;
                    sigmay[klabels[ind]] += r;
                    clustersize[klabels[ind]] += 1.0;
                }
                ind++;
            }
        }
        
		{for( k = 0; k < numk; k++ )
		{
			if( clustersize[k] <= 0 ) clustersize[k] = 1;
			inv[k] = 1.0/clustersize[k];//computing inverse now to multiply, than divide later
		}}
		
		{for( k = 0; k < numk; k++ )
		{
			kseedsl[k] = sigmal[k]*inv[k];
			kseedsa[k] = sigmaa[k]*inv[k];
			kseedsb[k] = sigmab[k]*inv[k];
			kseedsx[k] = sigmax[k]*inv[k];
			kseedsy[k] = sigmay[k]*inv[k];
		}}
	}
    mxFree(sigmal);
    mxFree(sigmaa);
    mxFree(sigmab);
    mxFree(sigmax);
    mxFree(sigmay);
    mxFree(clustersize);
    mxFree(inv);
    mxFree(distvec);
}
Exemplo n.º 14
0
void mexFunction(int nlhs, mxArray *plhs[],
				 int nrhs,  const mxArray *prhs[])
{
	
	
	double *S , *w;
	
	double *Smean , *Pcov;
	
	double *Stemp;
	
	
	const int *dimsS, *dimsw;
	
	int *dimsSmean , *dimsPcov;
	
	
	int numdimsS , numdimsw;
	
	int numdimsSmean , numdimsPcov;
	
	int i;
	
	int  d , N , slice=1;
	
	
	
	
	if((nrhs < 1) ||  (nrhs > 3)  )    
		
	{
		mexErrMsgTxt("Usage: [Smean , Pcov] = part_moment(S , w);");
		
	}
	/* --- Input 1 ---*/
	
    S        = mxGetPr(prhs[0]);
    
    numdimsS = mxGetNumberOfDimensions(prhs[0]);
    
	dimsS    = mxGetDimensions(prhs[0]);
	
	
	
	d        = dimsS[0];
	
	N        = dimsS[1];
	
	
	for (i = 2 ; i < numdimsS ; i++)
		
	{
		
		slice *= dimsS[i];
		
		
	}
	
	
	/* --- Input 2 ---*/
	
    w        = mxGetPr(prhs[1]);
    
    numdimsw = mxGetNumberOfDimensions(prhs[1]);
    
	dimsw    = mxGetDimensions(prhs[1]);
	
	if (numdimsw != 2)
		
	{	
		
		mexErrMsgTxt("Second input be (1 x N) or (N x 1");
		
	}
	
	if (max(dimsw[0] , dimsw[1]) != N)
		
	{	
		
		mexErrMsgTxt("Second input be (1 x N) or (N x 1");
		
	}
		
	
	/* --- Output 1 ---*/
	
	
    dimsSmean  = (int *)mxMalloc(numdimsS*sizeof(int));
	
	dimsSmean[0] = d;
	
	dimsSmean[1] = 1;
	
	for (i = 2 ; i < numdimsS ; i++)
		
	{
		
		dimsSmean[i] = dimsS[i];
		
	}
	
	numdimsSmean   = numdimsS;
	
	
	plhs[0]        = mxCreateNumericArray(numdimsSmean, dimsSmean, mxDOUBLE_CLASS, mxREAL);
	
	Smean          = mxGetPr(plhs[0]);
	
	
    dimsPcov       = (int *)mxMalloc(numdimsS*sizeof(int));
	
	dimsPcov[0]    = d;
	
	dimsPcov[1]    = d;
	
	for (i = 2 ; i < numdimsS ; i++)
		
	{
		
		dimsPcov[i] = dimsS[i];
		
	}
	
	numdimsPcov    = numdimsS;
	
	
	plhs[1]        = mxCreateNumericArray(numdimsPcov, dimsPcov, mxDOUBLE_CLASS, mxREAL);
	
	Pcov           = mxGetPr(plhs[1]);
	
	
	
	
	Stemp          =  (double *)mxMalloc(slice*d*N*sizeof(double));
	
	
	
	
	/*---------- Main Call --------- */
	
    
	part_moment(S , w , Smean ,  Pcov , Stemp , d , N , slice );
	
	/*------------------------------ */
	
	
	mxFree(Stemp);
	
	mxFree(dimsSmean);
	
	mxFree(dimsPcov);
	
}
Exemplo n.º 15
0
void mexFunction(int nlhs, mxArray  *plhs[], int nrhs, const mxArray  *prhs[])
{
	int atria_preprocessing_given = 0;		// flag wheter preprocessing is already given on command line
	long opt_flag = 0;	// 0 => eucl.norm, upper triangle matrix, 1 => max.norm, utm, 2 => eucl,full matrix, 3 => max.,full matrix

	be_verbose = 0; // Don't spit out feedback to user by default

	// try to see if the first parameter given is an atria structure
	// If this is true, the order of input parameters is shifted by one
	if ((nrhs > 0) && mxIsStruct(prhs[0])) {
		atria_preprocessing_given = 1;
		prhs++; 	// these two lines enable us to use the old argument parsing block without changing it
		nrhs--;
	}

	/* check input args */
	if (nrhs < 3)
	{
		mexErrMsgTxt("Correlation sum : Data set of points (row vectors), reference points and relative range (relative to attractor diameter) must be given, number of bins is optional");
		return;
	}

	if (nrhs > 4) opt_flag = (long) *((double *)mxGetPr(prhs[4]));

	if (opt_flag & (long) 2)
		be_verbose = 0;

	if (atria_preprocessing_given) {
#ifdef MATLAB_MEX_FILE
		char* metric = 0;

		if (mxIsChar(mxGetField(prhs[-1], 0, "optional"))) {
    		long buflen = (mxGetM(mxGetField(prhs[-1], 0, "optional")) * mxGetN(mxGetField(prhs[-1], 0, "optional"))) + 1;
 			metric = (char*) mxMalloc(buflen);
        	mxGetString(mxGetField(prhs[-1], 0, "optional"), metric, buflen);
		}

		if ((metric == 0) || (!strncmp("euclidian", metric, strlen(metric)))) {
			euclidian_distance dummy;

			if (be_verbose)
				mexPrintf("Using euclidian metric to calculated distances\n");

			compute(nlhs, plhs, nrhs, prhs, 1, dummy);
		}
		else if ((!strncmp("maximum", metric, strlen(metric)))) {
			maximum_distance dummy;

			if (be_verbose)
				mexPrintf("Using maximum metric to calculated distances\n");

			compute(nlhs, plhs, nrhs, prhs, 1, dummy);
		}
		else
			printf("ATRIA preprocessing structure was not created using a supported metric; doing preprocessing again\n");

		mxFree(metric);
#endif
	} else {
		if (opt_flag & (long)1) {
			maximum_distance dummy;

			if (be_verbose)
				mexPrintf("Using maximum metric to calculated distances\n");
			compute(nlhs, plhs, nrhs, prhs, 0, dummy);
		} else {
			euclidian_distance dummy;
			if (be_verbose)
				mexPrintf("Using euclidian metric to calculated distances\n");

			compute(nlhs, plhs, nrhs, prhs, 0, dummy);
		}
	}
}
Exemplo n.º 16
0
void homogToInds(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
  /* [rs,cs,is]=homogToInds(H,m,n,r0,r1,c0,c1,flag); */
  int m, n, flag; double *H, r0, r1, c0, c1;
  int *is, m1, n1, ind=0, i, j, fr, fc; double *rs, *cs, r, c, m2, n2, z;

  /* extract inputs */
  H  = (double*) mxGetData(prhs[0]);
  m  = (int) mxGetScalar(prhs[1]);
  n  = (int) mxGetScalar(prhs[2]);
  r0 = mxGetScalar(prhs[3]);
  r1 = mxGetScalar(prhs[4]);
  c0 = mxGetScalar(prhs[5]);
  c1 = mxGetScalar(prhs[6]);
  flag = (int) mxGetScalar(prhs[7]);

  /* initialize memory */
  m1  = (int) (r1-r0+1); m2 = (m+1.0)/2.0;
  n1  = (int) (c1-c0+1); n2 = (n+1.0)/2.0;
  rs  = mxMalloc(sizeof(double)*m1*n1);
  cs  = mxMalloc(sizeof(double)*m1*n1);
  is  = mxMalloc(sizeof(int)*m1*n1);

  /* Compute rs an cs */
  if( H[2]==0 && H[5]==0 ) {
    for( i=0; i<n1; i++ ) {
      r = H[0]*r0 + H[3]*(c0+i) + H[6] + m2;
      c = H[1]*r0 + H[4]*(c0+i) + H[7] + n2;
      for(j=0; j<m1; j++) {
        rs[ind]=r; cs[ind]=c;
        r+=H[0]; c+=H[1]; ind++;
      }
    }
  } else {
    for( i=0; i<n1; i++ ) {
      r = H[0]*r0 + H[3]*(c0+i) + H[6];
      c = H[1]*r0 + H[4]*(c0+i) + H[7];
      z = H[2]*r0 + H[5]*(c0+i) + 1;
      for(j=0; j<m1; j++) {
        rs[ind]=r/z+m2; cs[ind]=c/z+n2;
        r+=H[0]; c+=H[1]; z+=H[2]; ind++;
      }
    }
  }

  /* clamp and compute ids according to flag */
  if( flag==1 ) { /* nearest neighbor */
    for(i=0; i<n1*m1; i++) {
      r = rs[i]<1 ? 1 : (rs[i]>m ? m : rs[i]);
      c = cs[i]<1 ? 1 : (cs[i]>n ? n : cs[i]);
      is[i] = ((int) (r-.5)) + ((int) (c-.5)) * m;
    }
  } else if(flag==2) { /* bilinear */
    for(i=0; i<n1*m1; i++) {
      r = rs[i]<2 ? 2 : (rs[i]>m-1 ? m-1 : rs[i]);
      c = cs[i]<2 ? 2 : (cs[i]>n-1 ? n-1 : cs[i]);
      fr = (int) r; fc = (int) c;
      rs[i]=r-fr; cs[i]=c-fc; is[i]=(fr-1)+(fc-1)*m;
    }
  } else { /* other cases - clamp only */
    for(i=0; i<n1*m1; i++) {
      rs[i] = rs[i]<2 ? 2 : (rs[i]>m-1 ? m-1 : rs[i]);
      cs[i] = cs[i]<2 ? 2 : (cs[i]>n-1 ? n-1 : cs[i]);
    }
  }

  /* create output array */
  plhs[0] = mxCreateNumericMatrix(0,0,mxDOUBLE_CLASS,mxREAL);
  plhs[1] = mxCreateNumericMatrix(0,0,mxDOUBLE_CLASS,mxREAL);
  plhs[2] = mxCreateNumericMatrix(0,0,mxINT32_CLASS,mxREAL);
  mxSetData(plhs[0],rs); mxSetM(plhs[0],m1); mxSetN(plhs[0],n1);
  mxSetData(plhs[1],cs); mxSetM(plhs[1],m1); mxSetN(plhs[1],n1);
  mxSetData(plhs[2],is); mxSetM(plhs[2],m1); mxSetN(plhs[2],n1);
}
Exemplo n.º 17
0
void mexFunction( int nlhs, mxArray *plhs[] , int nrhs, const mxArray *prhs[] )
{
    int ny = 24 , nx = 24;
	double *scale;
	int Nscale = 0;
	int nF;
	unsigned int *F;
	int *dimsF;

    /* Input 1  */    
    if ((nrhs > 0) && (int)mxIsScalar(prhs[0]) )
    {        
        ny        = (int) mxGetScalar(prhs[0]);
    }
	if(ny < 3)
	{
		mexErrMsgTxt("ny must be >= 3");
	}
    
    /* Input 2  */
    
    if ((nrhs > 1) && (int)mxIsScalar(prhs[1]) )    
    {        
        nx        = (int) mxGetScalar(prhs[1]);
		if(nx < 3)
		{
			mexErrMsgTxt("nx must be >= 3");		
		}
    }
	else
	{	
		nx        = ny;	
	}
    if ((nrhs > 2) && !mxIsEmpty(prhs[2]) )
	{
		if(mxGetM(prhs[2]) !=2)
		{		
			mexErrMsgTxt("scale must be a (2 x Nscale) matrix");	
		}
		scale     = mxGetPr(prhs[2]);
		Nscale    = mxGetN(prhs[2]);
	}

	nF            = number_mblbp_features(ny , nx , scale , Nscale);

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

	dimsF         = (int *)mxMalloc(2*sizeof(int));
	dimsF[0]      = 5;
	dimsF[1]      = nF;
	plhs[0]       = mxCreateNumericArray(2 , dimsF , mxUINT32_CLASS , mxREAL);
	F             = (unsigned int *)mxGetPr(plhs[0]);

    /*------------------------ Main Call ----------------------------*/
      
    mblbp_featlist(ny , nx , scale , Nscale, F);
    
	/*----------------- Free Memory --------------------------------*/

	mxFree(dimsF);
}
Exemplo n.º 18
0
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *Prhs[])
{
register int i;
register double *pdbl;
mxArray **prhs=(mxArray **)&Prhs[0], *At, *Ct;
struct mexdata mdata;
int len, status;
double *p, *p0, *ret, *x;
int m, n, havejac, Arows, Crows, itmax, nopts, mintype, nextra;
double opts[LM_OPTS_SZ]={LM_INIT_MU, LM_STOP_THRESH, LM_STOP_THRESH, LM_STOP_THRESH, LM_DIFF_DELTA};
double info[LM_INFO_SZ];
double *lb=NULL, *ub=NULL, *A=NULL, *b=NULL, *wghts=NULL, *C=NULL, *d=NULL, *covar=NULL;

  /* parse input args; start by checking their number */
  if((nrhs<5))
    matlabFmtdErrMsgTxt("levmar: at least 5 input arguments required (got %d).", nrhs);
  if(nlhs>4)
    matlabFmtdErrMsgTxt("levmar: too many output arguments (max. 4, got %d).", nlhs);
  else if(nlhs<2)
    matlabFmtdErrMsgTxt("levmar: too few output arguments (min. 2, got %d).", nlhs);
    
  /* note that in order to accommodate optional args, prhs & nrhs are adjusted accordingly below */

  /** func **/
  /* first argument must be a string , i.e. a char row vector */
  if(mxIsChar(prhs[0])!=1)
    mexErrMsgTxt("levmar: first argument must be a string.");
  if(mxGetM(prhs[0])!=1)
    mexErrMsgTxt("levmar: first argument must be a string (i.e. char row vector).");
  /* store supplied name */
  len=mxGetN(prhs[0])+1;
  mdata.fname=mxCalloc(len, sizeof(char));
  status=mxGetString(prhs[0], mdata.fname, len);
  if(status!=0)
    mexErrMsgTxt("levmar: not enough space. String is truncated.");

  /** jac (optional) **/
  /* check whether second argument is a string */
  if(mxIsChar(prhs[1])==1){
    if(mxGetM(prhs[1])!=1)
      mexErrMsgTxt("levmar: second argument must be a string (i.e. row vector).");
    /* store supplied name */
    len=mxGetN(prhs[1])+1;
    mdata.jacname=mxCalloc(len, sizeof(char));
    status=mxGetString(prhs[1], mdata.jacname, len);
    if(status!=0)
      mexErrMsgTxt("levmar: not enough space. String is truncated.");
    havejac=1;

    ++prhs;
    --nrhs;
  }
  else{
    mdata.jacname=NULL;
    havejac=0;
  }

#ifdef DEBUG
  fflush(stderr);
  fprintf(stderr, "LEVMAR: %s analytic Jacobian\n", havejac? "with" : "no");
#endif /* DEBUG */

/* CHECK 
if(!mxIsDouble(prhs[1]) || mxIsComplex(prhs[1]) || !(mxGetM(prhs[1])==1 && mxGetN(prhs[1])==1))
*/

  /** p0 **/
  /* the second required argument must be a real row or column vector */
  if(!mxIsDouble(prhs[1]) || mxIsComplex(prhs[1]) || !(mxGetM(prhs[1])==1 || mxGetN(prhs[1])==1))
    mexErrMsgTxt("levmar: p0 must be a real vector.");
  p0=mxGetPr(prhs[1]);
  /* determine if we have a row or column vector and retrieve its 
   * size, i.e. the number of parameters
   */
  if(mxGetM(prhs[1])==1){
    m=mxGetN(prhs[1]);
    mdata.isrow_p0=1;
  }
  else{
    m=mxGetM(prhs[1]);
    mdata.isrow_p0=0;
  }
  /* copy input parameter vector to avoid destroying it */
  p=mxMalloc(m*sizeof(double));
  for(i=0; i<m; ++i)
    p[i]=p0[i];
    
  /** x **/
  /* the third required argument must be a real row or column vector */
  if(!mxIsDouble(prhs[2]) || mxIsComplex(prhs[2]) || !(mxGetM(prhs[2])==1 || mxGetN(prhs[2])==1))
    mexErrMsgTxt("levmar: x must be a real vector.");
  x=mxGetPr(prhs[2]);
  n=__MAX__(mxGetM(prhs[2]), mxGetN(prhs[2]));

  /** itmax **/
  /* the fourth required argument must be a scalar */
  if(!mxIsDouble(prhs[3]) || mxIsComplex(prhs[3]) || mxGetM(prhs[3])!=1 || mxGetN(prhs[3])!=1)
    mexErrMsgTxt("levmar: itmax must be a scalar.");
  itmax=(int)mxGetScalar(prhs[3]);
    
  /** opts **/
  /* the fifth required argument must be a real row or column vector */
  if(!mxIsDouble(prhs[4]) || mxIsComplex(prhs[4]) || (!(mxGetM(prhs[4])==1 || mxGetN(prhs[4])==1) &&
                                                      !(mxGetM(prhs[4])==0 && mxGetN(prhs[4])==0)))
    mexErrMsgTxt("levmar: opts must be a real vector.");
  pdbl=mxGetPr(prhs[4]);
  nopts=__MAX__(mxGetM(prhs[4]), mxGetN(prhs[4]));
  if(nopts!=0){ /* if opts==[], nothing needs to be done and the defaults are used */
    if(nopts>LM_OPTS_SZ)
      matlabFmtdErrMsgTxt("levmar: opts must have at most %d elements, got %d.", LM_OPTS_SZ, nopts);
    else if(nopts<((havejac)? LM_OPTS_SZ-1 : LM_OPTS_SZ))
      matlabFmtdWarnMsgTxt("levmar: only the %d first elements of opts specified, remaining set to defaults.", nopts);
    for(i=0; i<nopts; ++i)
      opts[i]=pdbl[i];
  }
#ifdef DEBUG
  else{
    fflush(stderr);
    fprintf(stderr, "LEVMAR: empty options vector, using defaults\n");
  }
#endif /* DEBUG */

  /** mintype (optional) **/
  /* check whether sixth argument is a string */
  if(nrhs>=6 && mxIsChar(prhs[5])==1 && mxGetM(prhs[5])==1){
    char *minhowto;

    /* examine supplied name */
    len=mxGetN(prhs[5])+1;
    minhowto=mxCalloc(len, sizeof(char));
    status=mxGetString(prhs[5], minhowto, len);
    if(status!=0)
      mexErrMsgTxt("levmar: not enough space. String is truncated.");

    for(i=0; minhowto[i]; ++i)
      minhowto[i]=tolower(minhowto[i]);
    if(!strncmp(minhowto, "unc", 3)) mintype=MIN_UNCONSTRAINED;
    else if(!strncmp(minhowto, "bc", 2)) mintype=MIN_CONSTRAINED_BC;
    else if(!strncmp(minhowto, "lec", 3)) mintype=MIN_CONSTRAINED_LEC;
    else if(!strncmp(minhowto, "blec", 4)) mintype=MIN_CONSTRAINED_BLEC;
    else if(!strncmp(minhowto, "bleic", 5)) mintype=MIN_CONSTRAINED_BLEIC;
    else if(!strncmp(minhowto, "blic", 4)) mintype=MIN_CONSTRAINED_BLIC;
    else if(!strncmp(minhowto, "leic", 4)) mintype=MIN_CONSTRAINED_LEIC;
    else if(!strncmp(minhowto, "lic", 3)) mintype=MIN_CONSTRAINED_BLIC;
    else matlabFmtdErrMsgTxt("levmar: unknown minimization type '%s'.", minhowto);

    mxFree(minhowto);

    ++prhs;
    --nrhs;
  }
  else
    mintype=MIN_UNCONSTRAINED;

  if(mintype==MIN_UNCONSTRAINED) goto extraargs;

  /* arguments below this point are optional and their presence depends
   * upon the minimization type determined above
   */
  /** lb, ub **/
  if(nrhs>=7 && (mintype==MIN_CONSTRAINED_BC || mintype==MIN_CONSTRAINED_BLEC || mintype==MIN_CONSTRAINED_BLIC || mintype==MIN_CONSTRAINED_BLEIC)){
    /* check if the next two arguments are real row or column vectors */
    if(mxIsDouble(prhs[5]) && !mxIsComplex(prhs[5]) && (mxGetM(prhs[5])==1 || mxGetN(prhs[5])==1)){
      if(mxIsDouble(prhs[6]) && !mxIsComplex(prhs[6]) && (mxGetM(prhs[6])==1 || mxGetN(prhs[6])==1)){
        if((i=__MAX__(mxGetM(prhs[5]), mxGetN(prhs[5])))!=m)
          matlabFmtdErrMsgTxt("levmar: lb must have %d elements, got %d.", m, i);
        if((i=__MAX__(mxGetM(prhs[6]), mxGetN(prhs[6])))!=m)
          matlabFmtdErrMsgTxt("levmar: ub must have %d elements, got %d.", m, i);

        lb=mxGetPr(prhs[5]);
        ub=mxGetPr(prhs[6]);

        prhs+=2;
        nrhs-=2;
      }
    }
  }

  /** A, b **/
  if(nrhs>=7 && (mintype==MIN_CONSTRAINED_LEC || mintype==MIN_CONSTRAINED_BLEC || mintype==MIN_CONSTRAINED_LEIC || mintype==MIN_CONSTRAINED_BLEIC)){
    /* check if the next two arguments are a real matrix and a real row or column vector */
    if(mxIsDouble(prhs[5]) && !mxIsComplex(prhs[5]) && mxGetM(prhs[5])>=1 && mxGetN(prhs[5])>=1){
      if(mxIsDouble(prhs[6]) && !mxIsComplex(prhs[6]) && (mxGetM(prhs[6])==1 || mxGetN(prhs[6])==1)){
        if((i=mxGetN(prhs[5]))!=m)
          matlabFmtdErrMsgTxt("levmar: A must have %d columns, got %d.", m, i);
        if((i=__MAX__(mxGetM(prhs[6]), mxGetN(prhs[6])))!=(Arows=mxGetM(prhs[5])))
          matlabFmtdErrMsgTxt("levmar: b must have %d elements, got %d.", Arows, i);

        At=prhs[5];
        b=mxGetPr(prhs[6]);
        A=getTranspose(At);

        prhs+=2;
        nrhs-=2;
      }
    }
  }

  /* wghts */
  /* check if we have a weights vector */
  if(nrhs>=6 && mintype==MIN_CONSTRAINED_BLEC){ /* only check if we have seen both box & linear constraints */
    if(mxIsDouble(prhs[5]) && !mxIsComplex(prhs[5]) && (mxGetM(prhs[5])==1 || mxGetN(prhs[5])==1)){
      if(__MAX__(mxGetM(prhs[5]), mxGetN(prhs[5]))==m){
        wghts=mxGetPr(prhs[5]);

        ++prhs;
        --nrhs;
      }
    }
  }

  /** C, d **/
  if(nrhs>=7 && (mintype==MIN_CONSTRAINED_BLEIC || mintype==MIN_CONSTRAINED_BLIC || mintype==MIN_CONSTRAINED_LEIC || mintype==MIN_CONSTRAINED_LIC)){
    /* check if the next two arguments are a real matrix and a real row or column vector */
    if(mxIsDouble(prhs[5]) && !mxIsComplex(prhs[5]) && mxGetM(prhs[5])>=1 && mxGetN(prhs[5])>=1){
      if(mxIsDouble(prhs[6]) && !mxIsComplex(prhs[6]) && (mxGetM(prhs[6])==1 || mxGetN(prhs[6])==1)){
        if((i=mxGetN(prhs[5]))!=m)
          matlabFmtdErrMsgTxt("levmar: C must have %d columns, got %d.", m, i);
        if((i=__MAX__(mxGetM(prhs[6]), mxGetN(prhs[6])))!=(Crows=mxGetM(prhs[5])))
          matlabFmtdErrMsgTxt("levmar: d must have %d elements, got %d.", Crows, i);

        Ct=prhs[5];
        d=mxGetPr(prhs[6]);
        C=getTranspose(Ct);

        prhs+=2;
        nrhs-=2;
      }
    }
  }

  /* arguments below this point are assumed to be extra arguments passed
   * to every invocation of the fitting function and its Jacobian
   */

extraargs:
  /* handle any extra args and allocate memory for
   * passing the current parameter estimate to matlab
   */
  nextra=nrhs-5;
  mdata.nrhs=nextra+1;
  mdata.rhs=(mxArray **)mxMalloc(mdata.nrhs*sizeof(mxArray *));
  for(i=0; i<nextra; ++i)
    mdata.rhs[i+1]=(mxArray *)prhs[nrhs-nextra+i]; /* discard 'const' modifier */
#ifdef DEBUG
  fflush(stderr);
  fprintf(stderr, "LEVMAR: %d extra args\n", nextra);
#endif /* DEBUG */

  if(mdata.isrow_p0){ /* row vector */
    mdata.rhs[0]=mxCreateDoubleMatrix(1, m, mxREAL);
    /*
    mxSetM(mdata.rhs[0], 1);
    mxSetN(mdata.rhs[0], m);
    */
  }
  else{ /* column vector */
    mdata.rhs[0]=mxCreateDoubleMatrix(m, 1, mxREAL);
    /*
    mxSetM(mdata.rhs[0], m);
    mxSetN(mdata.rhs[0], 1);
    */
  }

  /* ensure that the supplied function & Jacobian are as expected */
  if(checkFuncAndJacobian(p, m, n, havejac, &mdata)){
    status=LM_ERROR;
    goto cleanup;
  }

  if(nlhs>3) /* covariance output required */
    covar=mxMalloc(m*m*sizeof(double));

  /* invoke levmar */
  switch(mintype){
    case MIN_UNCONSTRAINED: /* no constraints */
      if(havejac)
        status=dlevmar_der(func, jacfunc, p, x, m, n, itmax, opts, info, NULL, covar, (void *)&mdata);
      else
        status=dlevmar_dif(func,          p, x, m, n, itmax, opts, info, NULL, covar, (void *)&mdata);
#ifdef DEBUG
  fflush(stderr);
  fprintf(stderr, "LEVMAR: calling dlevmar_der()/dlevmar_dif()\n");
#endif /* DEBUG */
    break;
    case MIN_CONSTRAINED_BC: /* box constraints */
      if(havejac)
        status=dlevmar_bc_der(func, jacfunc, p, x, m, n, lb, ub, itmax, opts, info, NULL, covar, (void *)&mdata);
      else
        status=dlevmar_bc_dif(func,          p, x, m, n, lb, ub, itmax, opts, info, NULL, covar, (void *)&mdata);
#ifdef DEBUG
  fflush(stderr);
  fprintf(stderr, "LEVMAR: calling dlevmar_bc_der()/dlevmar_bc_dif()\n");
#endif /* DEBUG */
    break;
    case MIN_CONSTRAINED_LEC:  /* linear equation constraints */
#ifdef HAVE_LAPACK
      if(havejac)
        status=dlevmar_lec_der(func, jacfunc, p, x, m, n, A, b, Arows, itmax, opts, info, NULL, covar, (void *)&mdata);
      else
        status=dlevmar_lec_dif(func,          p, x, m, n, A, b, Arows, itmax, opts, info, NULL, covar, (void *)&mdata);
#else
      mexErrMsgTxt("levmar: no linear constraints support, HAVE_LAPACK was not defined during MEX-file compilation.");
#endif /* HAVE_LAPACK */

#ifdef DEBUG
  fflush(stderr);
  fprintf(stderr, "LEVMAR: calling dlevmar_lec_der()/dlevmar_lec_dif()\n");
#endif /* DEBUG */
    break;
    case MIN_CONSTRAINED_BLEC: /* box & linear equation constraints */
#ifdef HAVE_LAPACK
      if(havejac)
        status=dlevmar_blec_der(func, jacfunc, p, x, m, n, lb, ub, A, b, Arows, wghts, itmax, opts, info, NULL, covar, (void *)&mdata);
      else
        status=dlevmar_blec_dif(func,          p, x, m, n, lb, ub, A, b, Arows, wghts, itmax, opts, info, NULL, covar, (void *)&mdata);
#else
      mexErrMsgTxt("levmar: no box & linear constraints support, HAVE_LAPACK was not defined during MEX-file compilation.");
#endif /* HAVE_LAPACK */

#ifdef DEBUG
  fflush(stderr);
  fprintf(stderr, "LEVMAR: calling dlevmar_blec_der()/dlevmar_blec_dif()\n");
#endif /* DEBUG */
    break;
    case MIN_CONSTRAINED_BLEIC: /* box, linear equation & inequalities constraints */
#ifdef HAVE_LAPACK
      if(havejac)
        status=dlevmar_bleic_der(func, jacfunc, p, x, m, n, lb, ub, A, b, Arows, C, d, Crows, itmax, opts, info, NULL, covar, (void *)&mdata);
      else
        status=dlevmar_bleic_dif(func, p, x, m, n, lb, ub, A, b, Arows, C, d, Crows, itmax, opts, info, NULL, covar, (void *)&mdata);
#else
      mexErrMsgTxt("levmar: no box, linear equation & inequality constraints support, HAVE_LAPACK was not defined during MEX-file compilation.");
#endif /* HAVE_LAPACK */

#ifdef DEBUG
  fflush(stderr);
  fprintf(stderr, "LEVMAR: calling dlevmar_bleic_der()/dlevmar_bleic_dif()\n");
#endif /* DEBUG */
    break;
    case MIN_CONSTRAINED_BLIC: /* box, linear inequalities constraints */
#ifdef HAVE_LAPACK
      if(havejac)
        status=dlevmar_bleic_der(func, jacfunc, p, x, m, n, lb, ub, NULL, NULL, 0, C, d, Crows, itmax, opts, info, NULL, covar, (void *)&mdata);
      else
        status=dlevmar_bleic_dif(func, p, x, m, n, lb, ub, NULL, NULL, 0, C, d, Crows, itmax, opts, info, NULL, covar, (void *)&mdata);
#else
      mexErrMsgTxt("levmar: no box & linear inequality constraints support, HAVE_LAPACK was not defined during MEX-file compilation.");
#endif /* HAVE_LAPACK */

#ifdef DEBUG
  fflush(stderr);
  fprintf(stderr, "LEVMAR: calling dlevmar_blic_der()/dlevmar_blic_dif()\n");
#endif /* DEBUG */
    break;
    case MIN_CONSTRAINED_LEIC: /* linear equation & inequalities constraints */
#ifdef HAVE_LAPACK
      if(havejac)
        status=dlevmar_bleic_der(func, jacfunc, p, x, m, n, NULL, NULL, A, b, Arows, C, d, Crows, itmax, opts, info, NULL, covar, (void *)&mdata);
      else
        status=dlevmar_bleic_dif(func, p, x, m, n, NULL, NULL, A, b, Arows, C, d, Crows, itmax, opts, info, NULL, covar, (void *)&mdata);
#else
      mexErrMsgTxt("levmar: no linear equation & inequality constraints support, HAVE_LAPACK was not defined during MEX-file compilation.");
#endif /* HAVE_LAPACK */

#ifdef DEBUG
  fflush(stderr);
  fprintf(stderr, "LEVMAR: calling dlevmar_leic_der()/dlevmar_leic_dif()\n");
#endif /* DEBUG */
    break;
    case MIN_CONSTRAINED_LIC: /* linear inequalities constraints */
#ifdef HAVE_LAPACK
      if(havejac)
        status=dlevmar_bleic_der(func, jacfunc, p, x, m, n, NULL, NULL, NULL, NULL, 0, C, d, Crows, itmax, opts, info, NULL, covar, (void *)&mdata);
      else
        status=dlevmar_bleic_dif(func, p, x, m, n, NULL, NULL, NULL, NULL, 0, C, d, Crows, itmax, opts, info, NULL, covar, (void *)&mdata);
#else
      mexErrMsgTxt("levmar: no linear equation & inequality constraints support, HAVE_LAPACK was not defined during MEX-file compilation.");
#endif /* HAVE_LAPACK */

#ifdef DEBUG
  fflush(stderr);
  fprintf(stderr, "LEVMAR: calling dlevmar_lic_der()/dlevmar_lic_dif()\n");
#endif /* DEBUG */
    break;
    default:
      mexErrMsgTxt("levmar: unexpected internal error.");
  }

#ifdef DEBUG
  fflush(stderr);
  printf("LEVMAR: minimization returned %d in %g iter, reason %g\n\tSolution: ", status, info[5], info[6]);
  for(i=0; i<m; ++i)
    printf("%.7g ", p[i]);
  printf("\n\n\tMinimization info:\n\t");
  for(i=0; i<LM_INFO_SZ; ++i)
    printf("%g ", info[i]);
  printf("\n");
#endif /* DEBUG */

  /* copy back return results */
  /** ret **/
  plhs[0]=mxCreateDoubleMatrix(1, 1, mxREAL);
  ret=mxGetPr(plhs[0]);
  ret[0]=(double)status;

  /** popt **/
  plhs[1]=(mdata.isrow_p0==1)? mxCreateDoubleMatrix(1, m, mxREAL) : mxCreateDoubleMatrix(m, 1, mxREAL);
  pdbl=mxGetPr(plhs[1]);
  for(i=0; i<m; ++i)
    pdbl[i]=p[i];

  /** info **/
  if(nlhs>2){
    plhs[2]=mxCreateDoubleMatrix(1, LM_INFO_SZ, mxREAL);
    pdbl=mxGetPr(plhs[2]);
    for(i=0; i<LM_INFO_SZ; ++i)
      pdbl[i]=info[i];
  }

  /** covar **/
  if(nlhs>3){
    plhs[3]=mxCreateDoubleMatrix(m, m, mxREAL);
    pdbl=mxGetPr(plhs[3]);
    for(i=0; i<m*m; ++i) /* covariance matrices are symmetric, thus no need to transpose! */
      pdbl[i]=covar[i];
  }

cleanup:
  /* cleanup */
  mxDestroyArray(mdata.rhs[0]);
  if(A) mxFree(A);
  if(C) mxFree(C);

  mxFree(mdata.fname);
  if(havejac) mxFree(mdata.jacname);
  mxFree(p);
  mxFree(mdata.rhs);
  if(covar) mxFree(covar);

  if(status==LM_ERROR)
    mexWarnMsgTxt("levmar: optimization returned with an error!");
}
Exemplo n.º 19
0
void mexFunction(int nlhs, mxArray *plhs[], int nrhs,
                 const mxArray *prhs[]) {



    /* Check for proper number of arguments. */
    if (nrhs != 3) {
        mexErrMsgTxt("Three inputs required.");
    }

    //the first argument is the array of vectors used to build the tree
    /*
      int nelements=mxGetNumberOfFields(prhs[0]);
    if(nelements!=1) {
      mexErrMsgTxt("Input should have one element.");
    }
    */

    //the second argument is the struct returned by covertree
    int nfields = mxGetNumberOfFields(prhs[1]);
    if(nfields!=8) {
        mexErrMsgTxt("Second input should have 8 fields.");
    }

    //the third argument is the struct whose first member is the array of
    //vectors being studied;
    //whose second member is the distance;
    //whose third member is the depth
    nfields = mxGetNumberOfFields(prhs[2]);
    if(nfields!=2) {
        mexErrMsgTxt("Third input should have two fields.");
    }

    const mxArray* tmp=0;

    //Check for proper number of return arguments; [D] or [D E] or [D E F]
    //Return argument one is a cell array D
    //D{i}=indices of A.vectors within distance of A.vectors(:,i) at right level
    //If two or more return arguments, E{i} is corresponding distances
    //F is diagnostics

    bool dist_flag=false;
    bool diag_flag=false;
    if(nlhs==3) {
        dist_flag=true;
        diag_flag=true;
    } else if (nlhs=3) {
        dist_flag=true;
    } else {
        if(nlhs!=1) {
            mexErrMsgTxt("One, two or three return arguments required\n");
        }
    }

    //Extract appropriate members from first input;
    //this is what what was passed to covertree

    tmp=prhs[0];
    mwSize ndims_in=mxGetNumberOfDimensions(tmp);
    const mwSize* dims_in=mxGetDimensions(tmp);

    int N=dims_in[ndims_in-1];
    int n=1;
    for(int i=0; i<ndims_in-1; i++) {
        n*=dims_in[i];
    }

    mexPrintf("n=%d N=%d\n",n,N);


    double* X=(double*)mxGetData(tmp);

    Vectors vectors(n,N,X);

    // Extract appropriate members from second input;
    //this is what was returned from covertree

    tmp=mxGetField(prhs[1],0,cover_in[0]);
    double* ptheta=(double*)mxGetData(tmp);
    double theta=*ptheta;

    tmp=mxGetField(prhs[1],0,cover_in[1]);
    int* params=(int*)mxGetData(tmp);

    tmp=mxGetField(prhs[1],0,cover_in[2]);
    int* lp=(int*)mxGetData(tmp);

    tmp=mxGetField(prhs[1],0,cover_in[3]);
    int* pchildren=(int*)mxGetData(tmp);
    DisjointLists children(N,pchildren,false);


    int* pdescend_list=(int*)mxMalloc(2*N*sizeof(int));
    int* pdist_flags=(int*)mxMalloc(N*sizeof(int));
    int* pindices_to_dist_flags=(int*)mxMalloc(N*sizeof(int));
    double* pdistances=(double*)mxMalloc(N*sizeof(double));
    int* pcurrent_child_flags=(int*)mxMalloc(N*sizeof(int));
    int* pindices_to_current_child_flags=(int*)mxMalloc(N*sizeof(int));
    int* pcurrent_children=(int*)mxMalloc(N*sizeof(int));

//Get third input

    //tmp=prhs[2];
    tmp=mxGetField(prhs[2],0,nearest_in[0]);
    ndims_in=mxGetNumberOfDimensions(tmp);
    dims_in=mxGetDimensions(tmp);


    int N2=dims_in[ndims_in-1];
    int n2=1;
    for(int i=0; i<ndims_in-1; i++) {
        n2*=dims_in[i];
    }

    mexPrintf("N2=%d\n",N2);

    if(n2!=n) {
        mexPrintf("n2=%d must equal n=%d\n",n2,n);
    }

    double* Y=(double*)mxGetData(tmp);

    tmp=mxGetField(prhs[2],0,nearest_in[1]);
    int* pk=(int*)mxGetData(tmp);
    int k=*pk;

    Cover cover(theta,
                params,
                &vectors,
                lp,children,
                pdescend_list,
                pdist_flags,pindices_to_dist_flags,
                pdistances,
                pcurrent_child_flags,pindices_to_current_child_flags,
                pcurrent_children);

    ndims=2;
    dims[0]=1;
    dims[1]=N2;

    mxArray* pointer0=mxCreateCellArray(ndims,dims);
    mxArray* pointer1=0;
    //Cover::DescendList* pdescendlist=0;
    if(dist_flag) {
        pointer1= mxCreateCellArray(ndims,dims);
        //pdescendlist=(Cover::DescendList*)&cover.getDescendList();
    }

    int* indices=(int*)mxMalloc(N*sizeof(int));
    double* d=(double*)mxMalloc(N*sizeof(double));
    int* Indices=(int*)mxMalloc(N*sizeof(int));
    double* D=(double*)mxMalloc(N*sizeof(double));

    for(int i=0; i<N2; i++) {
        //mexPrintf("loop i=%d\n",i);
        Vector v(n,Y+i*n);
        int K=cover.findNearest(&v,k,indices,d);
        dims[1]=K;
        mxArray* fout=mxCreateNumericArray(ndims,dims,mxINT32_CLASS,mxREAL);
        int* arr=(int*)mxGetData(fout);
        for(int j=0; j<K; j++) {
            arr[j]=indices[j];
        }

        /*
        bool test=cover.checkFindNearest(&v,k,K,indices,d,Indices,D);
        if(test) {
          mexPrintf("checkFindWithin passed\n");
        } else {
          mexPrintf("checkFindWithin failed\n");
        }
        mexPrintf("after mxSetCell i=%d\n",i);
        */

        mxSetCell(pointer0,i,fout);
        if(dist_flag) {
            fout=mxCreateNumericArray(ndims,dims,mxDOUBLE_CLASS,mxREAL);
            double* dist=(double*)mxGetData(fout);
            for(int j=0; j<K; j++) {
                //dist[i]=pdescendlist->getDist(&v,arr[i]);
                dist[j]=d[j];
            }
            mxSetCell(pointer1,i,fout);
        }
        cover.clearDescendList();
    }

    plhs[0]=pointer0;
    if(dist_flag) {
        plhs[1]=pointer1;
    }

    if(diag_flag) {
        double* p=0;
        plhs[2]= mxCreateStructMatrix(1, 1, 4, fnames_out_2);
        ndims=2;
        dims[0]=1;
        dims[1]=1;

        mxArray* fout=0;
        fout = mxCreateNumericArray(ndims,dims,mxDOUBLE_CLASS,mxREAL);
        p=(double*)mxGetData(fout);
        mxSetField(plhs[2],0,fnames_out_2[0],fout);
        p[0]=cover.getDistNCallsToGet();

        fout = mxCreateNumericArray(ndims,dims,mxDOUBLE_CLASS,mxREAL);
        p=(double*)mxGetData(fout);
        mxSetField(plhs[2],0,fnames_out_2[1],fout);
        p[0]=cover.getDistNCallsToSet();

        fout = mxCreateNumericArray(ndims,dims,mxDOUBLE_CLASS,mxREAL);
        p=(double*)mxGetData(fout);
        mxSetField(plhs[2],0,fnames_out_2[2],fout);
        p[0]=cover.getChildrenNCallsToGet();

        fout = mxCreateNumericArray(ndims,dims,mxDOUBLE_CLASS,mxREAL);
        p=(double*)mxGetData(fout);
        mxSetField(plhs[2],0,fnames_out_2[3],fout);
        p[0]=cover.getChildrenNCallsToSet();
    }

    mxFree(pdescend_list);
    mxFree(pdist_flags);
    mxFree(pindices_to_dist_flags);
    mxFree(pdistances);
    mxFree(pcurrent_child_flags);
    mxFree(pindices_to_current_child_flags);
    mxFree(pcurrent_children);

    mxFree(indices);
    mxFree(d);
    mxFree(Indices);
    mxFree(D);

}
Exemplo n.º 20
0
struct svm_model *matlab_matrix_to_model(const mxArray *matlab_struct, const char **msg)
{
	int i, j, n, num_of_fields;
	double *ptr;
	int id = 0;
	struct svm_node *x_space;
	struct svm_model *model;
	mxArray **rhs;

	num_of_fields = mxGetNumberOfFields(matlab_struct);
	if(num_of_fields != NUM_OF_RETURN_FIELD) 
	{
		*msg = "number of return field is not correct";
		return NULL;
	}
	rhs = (mxArray **) mxMalloc(sizeof(mxArray *)*num_of_fields);

	for(i=0;i<num_of_fields;i++)
		rhs[i] = mxGetFieldByNumber(matlab_struct, 0, i);

	model = Malloc(struct svm_model, 1);
	model->rho = NULL;
	model->probA = NULL;
	model->probB = NULL;
	model->label = NULL;
	model->nSV = NULL;
	model->free_sv = 1; /* XXX */

	ptr = mxGetPr(rhs[id]);
	model->param.svm_type = (int)ptr[0];
	model->param.kernel_type  = (int)ptr[1];
	model->param.degree	  = (int)ptr[2];
	model->param.gamma	  = ptr[3];
	model->param.coef0	  = ptr[4];
	id++;

	ptr = mxGetPr(rhs[id]);
	model->nr_class = (int)ptr[0];
	id++;

	ptr = mxGetPr(rhs[id]);
	model->l = (int)ptr[0];
	id++;

	/* rho */
	n = model->nr_class * (model->nr_class-1)/2;
	model->rho = (double*) malloc(n*sizeof(double));
	ptr = mxGetPr(rhs[id]);
	for(i=0;i<n;i++)
		model->rho[i] = ptr[i];
	id++;

	/* label */
	if(mxIsEmpty(rhs[id]) == 0)
	{
		model->label = (int*) malloc(model->nr_class*sizeof(int));
		ptr = mxGetPr(rhs[id]);
		for(i=0;i<model->nr_class;i++)
			model->label[i] = (int)ptr[i];
	}
	id++;

	/* probA */
	if(mxIsEmpty(rhs[id]) == 0)
	{
		model->probA = (double*) malloc(n*sizeof(double));
		ptr = mxGetPr(rhs[id]);
		for(i=0;i<n;i++)
			model->probA[i] = ptr[i];
	}
	id++;

	/* probB */
	if(mxIsEmpty(rhs[id]) == 0)
	{
		model->probB = (double*) malloc(n*sizeof(double));
		ptr = mxGetPr(rhs[id]);
		for(i=0;i<n;i++)
			model->probB[i] = ptr[i];
	}
	id++;

	/* nSV */
	if(mxIsEmpty(rhs[id]) == 0)
	{
		model->nSV = (int*) malloc(model->nr_class*sizeof(int));
		ptr = mxGetPr(rhs[id]);
		for(i=0;i<model->nr_class;i++)
			model->nSV[i] = (int)ptr[i];
	}
	id++;

	/* sv_coef */
	ptr = mxGetPr(rhs[id]);
	model->sv_coef = (double**) malloc((model->nr_class-1)*sizeof(double));
	for( i=0 ; i< model->nr_class -1 ; i++ )
		model->sv_coef[i] = (double*) malloc((model->l)*sizeof(double));
	for(i = 0; i < model->nr_class - 1; i++)
		for(j = 0; j < model->l; j++)
			model->sv_coef[i][j] = ptr[i*(model->l)+j];
	id++;

	/* SV */
	{
		int sr, sc, elements;
		int num_samples;
		mwIndex *ir, *jc;
		mxArray *pprhs[1], *pplhs[1];

		/* transpose SV */
		pprhs[0] = rhs[id];
		if(mexCallMATLAB(1, pplhs, 1, pprhs, "transpose")) 
		{
			svm_destroy_model(model);
			*msg = "cannot transpose SV matrix";
			return NULL;
		}
		rhs[id] = pplhs[0];

		sr = (int)mxGetN(rhs[id]);
		sc = (int)mxGetM(rhs[id]);

		ptr = mxGetPr(rhs[id]);
		ir = mxGetIr(rhs[id]);
		jc = mxGetJc(rhs[id]);

		num_samples = (int)mxGetNzmax(rhs[id]);

		elements = num_samples + sr;

		model->SV = (struct svm_node **) malloc(sr * sizeof(struct svm_node *));
		x_space = (struct svm_node *)malloc(elements * sizeof(struct svm_node));

		/* SV is in column */
		for(i=0;i<sr;i++)
		{
			int low = (int)jc[i], high = (int)jc[i+1];
			int x_index = 0;
			model->SV[i] = &x_space[low+i];
			for(j=low;j<high;j++)
			{
				model->SV[i][x_index].index = (int)ir[j] + 1; 
				model->SV[i][x_index].value = ptr[j];
				x_index++;
			}
			model->SV[i][x_index].index = -1;
		}

		id++;
	}
	mxFree(rhs);

	return model;
}
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
    //-----------------------
    // Input pointers
    
    double		    *h_fMRI_Volumes_double, *h_X_GLM_double, *h_xtxxt_GLM_double, *h_Contrasts_double, *h_ctxtxc_GLM_double;
    float           *h_fMRI_Volumes, *h_X_GLM, *h_xtxxt_GLM, *h_Contrasts, *h_ctxtxc_GLM;  
    
    double          *h_Mask_double;
    float           *h_Mask;
        
    int             OPENCL_PLATFORM, OPENCL_DEVICE;
    
    //-----------------------
    // Output pointers        
    
    double     		*h_Beta_Volumes_double, *h_Residuals_double, *h_Residual_Variances_double, *h_Statistical_Maps_double;    
    float           *h_Beta_Volumes, *h_Residuals, *h_Residual_Variances, *h_Statistical_Maps;
        
    //---------------------
    
    /* Check the number of input and output arguments. */
    if(nrhs<8)
    {
        mexErrMsgTxt("Too few input arguments.");
    }
    if(nrhs>8)
    {
        mexErrMsgTxt("Too many input arguments.");
    }
    if(nlhs<4)
    {
        mexErrMsgTxt("Too few output arguments.");
    }
    if(nlhs>4)
    {
        mexErrMsgTxt("Too many output arguments.");
    }
    
    /* Input arguments */
    
    // The data
    h_fMRI_Volumes_double =  (double*)mxGetData(prhs[0]);
    h_Mask_double =  (double*)mxGetData(prhs[1]);
    h_X_GLM_double =  (double*)mxGetData(prhs[2]);
    h_xtxxt_GLM_double =  (double*)mxGetData(prhs[3]);
    h_Contrasts_double = (double*)mxGetData(prhs[4]);
    h_ctxtxc_GLM_double = (double*)mxGetData(prhs[5]);
    OPENCL_PLATFORM  = (int)mxGetScalar(prhs[6]);
    OPENCL_DEVICE  = (int)mxGetScalar(prhs[7]);
    
    int NUMBER_OF_DIMENSIONS = mxGetNumberOfDimensions(prhs[0]);
    const int *ARRAY_DIMENSIONS_DATA = mxGetDimensions(prhs[0]);
    const int *ARRAY_DIMENSIONS_GLM = mxGetDimensions(prhs[2]);
    const int *ARRAY_DIMENSIONS_CONTRAST = mxGetDimensions(prhs[5]);
    
    int DATA_H, DATA_W, DATA_D, DATA_T, NUMBER_OF_REGRESSORS, NUMBER_OF_TOTAL_GLM_REGRESSORS, NUMBER_OF_CONTRASTS;
    
    DATA_H = ARRAY_DIMENSIONS_DATA[0];
    DATA_W = ARRAY_DIMENSIONS_DATA[1];
    DATA_D = ARRAY_DIMENSIONS_DATA[2];
    DATA_T = ARRAY_DIMENSIONS_DATA[3];
    
    NUMBER_OF_REGRESSORS = ARRAY_DIMENSIONS_GLM[1];
    NUMBER_OF_TOTAL_GLM_REGRESSORS = NUMBER_OF_REGRESSORS;    
    NUMBER_OF_CONTRASTS = ARRAY_DIMENSIONS_CONTRAST[1];
                
    int DATA_SIZE = DATA_W * DATA_H * DATA_D * DATA_T * sizeof(float);
    int VOLUME_SIZE = DATA_W * DATA_H * DATA_D * sizeof(float);
    int GLM_SIZE = DATA_T * NUMBER_OF_REGRESSORS * sizeof(float);
    int CONTRAST_SIZE = NUMBER_OF_REGRESSORS * NUMBER_OF_CONTRASTS * sizeof(float);
    int CONTRAST_MATRIX_SIZE = NUMBER_OF_CONTRASTS * NUMBER_OF_CONTRASTS * sizeof(float);
    int BETA_SIZE = DATA_W * DATA_H * DATA_D * NUMBER_OF_TOTAL_GLM_REGRESSORS * sizeof(float);
    int STATISTICAL_MAPS_SIZE = DATA_W * DATA_H * DATA_D * sizeof(float);
    int DESIGN_MATRIX_SIZE = NUMBER_OF_TOTAL_GLM_REGRESSORS * DATA_T * sizeof(float);
    
    mexPrintf("Data size : %i x %i x %i x %i \n",  DATA_W, DATA_H, DATA_D, DATA_T);
    mexPrintf("Number of regressors : %i \n",  NUMBER_OF_REGRESSORS);
    mexPrintf("Number of contrasts : %i \n",  NUMBER_OF_CONTRASTS);
    
    //-------------------------------------------------
    // Output to Matlab
    
    // Create pointer for volumes to Matlab        
    NUMBER_OF_DIMENSIONS = 4;
    int ARRAY_DIMENSIONS_OUT_BETA[4];
    ARRAY_DIMENSIONS_OUT_BETA[0] = DATA_H;
    ARRAY_DIMENSIONS_OUT_BETA[1] = DATA_W;
    ARRAY_DIMENSIONS_OUT_BETA[2] = DATA_D;
    ARRAY_DIMENSIONS_OUT_BETA[3] = NUMBER_OF_TOTAL_GLM_REGRESSORS;
    
    plhs[0] = mxCreateNumericArray(NUMBER_OF_DIMENSIONS,ARRAY_DIMENSIONS_OUT_BETA,mxDOUBLE_CLASS, mxREAL);
    h_Beta_Volumes_double = mxGetPr(plhs[0]);          
    
    NUMBER_OF_DIMENSIONS = 4;
    int ARRAY_DIMENSIONS_OUT_RESIDUALS[4];
    ARRAY_DIMENSIONS_OUT_RESIDUALS[0] = DATA_H;
    ARRAY_DIMENSIONS_OUT_RESIDUALS[1] = DATA_W;
    ARRAY_DIMENSIONS_OUT_RESIDUALS[2] = DATA_D;
    ARRAY_DIMENSIONS_OUT_RESIDUALS[3] = DATA_T;
    
    plhs[1] = mxCreateNumericArray(NUMBER_OF_DIMENSIONS,ARRAY_DIMENSIONS_OUT_RESIDUALS,mxDOUBLE_CLASS, mxREAL);
    h_Residuals_double = mxGetPr(plhs[1]);          
        
    NUMBER_OF_DIMENSIONS = 3;
    int ARRAY_DIMENSIONS_OUT_RESIDUAL_VARIANCES[3];
    ARRAY_DIMENSIONS_OUT_RESIDUAL_VARIANCES[0] = DATA_H;
    ARRAY_DIMENSIONS_OUT_RESIDUAL_VARIANCES[1] = DATA_W;
    ARRAY_DIMENSIONS_OUT_RESIDUAL_VARIANCES[2] = DATA_D;
    
    plhs[2] = mxCreateNumericArray(NUMBER_OF_DIMENSIONS,ARRAY_DIMENSIONS_OUT_RESIDUAL_VARIANCES,mxDOUBLE_CLASS, mxREAL);
    h_Residual_Variances_double = mxGetPr(plhs[2]);          
    
    NUMBER_OF_DIMENSIONS = 3;
    int ARRAY_DIMENSIONS_OUT_STATISTICAL_MAPS[3];
    ARRAY_DIMENSIONS_OUT_STATISTICAL_MAPS[0] = DATA_H;
    ARRAY_DIMENSIONS_OUT_STATISTICAL_MAPS[1] = DATA_W;
    ARRAY_DIMENSIONS_OUT_STATISTICAL_MAPS[2] = DATA_D;
    
    plhs[3] = mxCreateNumericArray(NUMBER_OF_DIMENSIONS,ARRAY_DIMENSIONS_OUT_STATISTICAL_MAPS,mxDOUBLE_CLASS, mxREAL);
    h_Statistical_Maps_double = mxGetPr(plhs[3]);                  
    
    // ------------------------------------------------
    
    // Allocate memory on the host
    h_fMRI_Volumes                 = (float *)mxMalloc(DATA_SIZE);
    h_Mask                     = (float *)mxMalloc(VOLUME_SIZE);
    
    h_X_GLM                        = (float *)mxMalloc(GLM_SIZE);
    h_xtxxt_GLM                    = (float *)mxMalloc(GLM_SIZE);
    h_Contrasts                    = (float *)mxMalloc(CONTRAST_SIZE);
    h_ctxtxc_GLM                   = (float *)mxMalloc(CONTRAST_MATRIX_SIZE);
    
    h_Beta_Volumes                 = (float *)mxMalloc(BETA_SIZE);
    h_Residuals                    = (float *)mxMalloc(DATA_SIZE);
    h_Residual_Variances           = (float *)mxMalloc(VOLUME_SIZE);
    h_Statistical_Maps             = (float *)mxMalloc(STATISTICAL_MAPS_SIZE);
        
    // Reorder and cast data
    pack_double2float_volumes(h_fMRI_Volumes, h_fMRI_Volumes_double, DATA_W, DATA_H, DATA_D, DATA_T);
    pack_double2float_volume(h_Mask, h_Mask_double, DATA_W, DATA_H, DATA_D);
    pack_double2float(h_X_GLM, h_X_GLM_double, NUMBER_OF_REGRESSORS * DATA_T);
    pack_double2float(h_xtxxt_GLM, h_xtxxt_GLM_double, NUMBER_OF_REGRESSORS * DATA_T);    
    pack_double2float_image(h_Contrasts, h_Contrasts_double, NUMBER_OF_REGRESSORS, NUMBER_OF_CONTRASTS);        
    pack_double2float(h_ctxtxc_GLM, h_ctxtxc_GLM_double, NUMBER_OF_CONTRASTS * NUMBER_OF_CONTRASTS);
    
    //------------------------
    
    BROCCOLI_LIB BROCCOLI(OPENCL_PLATFORM,OPENCL_DEVICE);
    
     // Something went wrong...
    if (BROCCOLI.GetOpenCLInitiated() == 0)
    {  
        int getPlatformIDsError = BROCCOLI.GetOpenCLPlatformIDsError();
        int getDeviceIDsError = BROCCOLI.GetOpenCLDeviceIDsError();                
        int createContextError = BROCCOLI.GetOpenCLCreateContextError();
        int getContextInfoError = BROCCOLI.GetOpenCLContextInfoError();
        int createCommandQueueError = BROCCOLI.GetOpenCLCreateCommandQueueError();
        int createProgramError = BROCCOLI.GetOpenCLCreateProgramError();
        int buildProgramError = BROCCOLI.GetOpenCLBuildProgramError();
        int getProgramBuildInfoError = BROCCOLI.GetOpenCLProgramBuildInfoError();
          
        mexPrintf("Get platform IDs error is %d \n",getPlatformIDsError);
        mexPrintf("Get device IDs error is %d \n",getDeviceIDsError);
        mexPrintf("Create context error is %d \n",createContextError);
        mexPrintf("Get create context info error is %d \n",getContextInfoError);
        mexPrintf("Create command queue error is %d \n",createCommandQueueError);
        mexPrintf("Create program error is %d \n",createProgramError);
        mexPrintf("Build program error is %d \n",buildProgramError);
        mexPrintf("Get program build info error is %d \n",getProgramBuildInfoError);
    
        // Print create kernel errors
        int* createKernelErrors = BROCCOLI.GetOpenCLCreateKernelErrors();
        for (int i = 0; i < BROCCOLI.GetNumberOfOpenCLKernels(); i++)
        {
            if (createKernelErrors[i] != 0)
            {
                mexPrintf("Create kernel error %i is %d \n",i,createKernelErrors[i]);
            }
        }
        
        mexPrintf("OPENCL initialization failed, aborting \n");        
    }
    else if (BROCCOLI.GetOpenCLInitiated() == 1)
    {
        BROCCOLI.SetMNIWidth(DATA_W);
        BROCCOLI.SetMNIHeight(DATA_H);
        BROCCOLI.SetMNIDepth(DATA_D);
        BROCCOLI.SetNumberOfSubjects(DATA_T);   
        BROCCOLI.SetNumberOfGLMRegressors(NUMBER_OF_REGRESSORS);
        BROCCOLI.SetNumberOfContrasts(NUMBER_OF_CONTRASTS);    
        BROCCOLI.SetInputFirstLevelResults(h_fMRI_Volumes);
        BROCCOLI.SetDesignMatrix(h_X_GLM, h_xtxxt_GLM);
        BROCCOLI.SetContrasts(h_Contrasts);
        BROCCOLI.SetGLMScalars(h_ctxtxc_GLM);
        BROCCOLI.SetMask(h_Mask);
        
        BROCCOLI.SetOutputBetaVolumes(h_Beta_Volumes);
        BROCCOLI.SetOutputResiduals(h_Residuals);
        BROCCOLI.SetOutputResidualVariances(h_Residual_Variances);
        BROCCOLI.SetOutputStatisticalMaps(h_Statistical_Maps);
        
        BROCCOLI.PerformGLMFTestSecondLevelWrapper();
        
        // 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 run kernel errors
        int* runKernelErrors = BROCCOLI.GetOpenCLRunKernelErrors();
        for (int i = 0; i < BROCCOLI.GetNumberOfOpenCLKernels(); i++)
        {
            if (runKernelErrors[i] != 0)
            {
                mexPrintf("Run kernel error %i is %d \n",i,runKernelErrors[i]);
            }
        } 
    }

    mexPrintf("Build info \n \n %s \n", BROCCOLI.GetOpenCLBuildInfoChar());  
    
    unpack_float2double_volumes(h_Beta_Volumes_double, h_Beta_Volumes, DATA_W, DATA_H, DATA_D, NUMBER_OF_TOTAL_GLM_REGRESSORS);
    unpack_float2double_volumes(h_Residuals_double, h_Residuals, DATA_W, DATA_H, DATA_D, DATA_T);
    unpack_float2double_volume(h_Residual_Variances_double, h_Residual_Variances, DATA_W, DATA_H, DATA_D);
    unpack_float2double_volume(h_Statistical_Maps_double, h_Statistical_Maps, DATA_W, DATA_H, DATA_D);
           
    // Free all the allocated memory on the host
        
    mxFree(h_fMRI_Volumes);
    mxFree(h_Mask);
    
    mxFree(h_X_GLM);
    mxFree(h_xtxxt_GLM);    
    mxFree(h_Contrasts);
    mxFree(h_ctxtxc_GLM);
    
    mxFree(h_Beta_Volumes);
    mxFree(h_Residuals);
    mxFree(h_Residual_Variances);
    mxFree(h_Statistical_Maps);
    
    
    return;
}
Exemplo n.º 22
0
const char *model_to_matlab_structure(mxArray *plhs[], int num_of_feature, struct svm_model *model)
{
	int i, j, n;
	double *ptr;
	mxArray *return_model, **rhs;
	int out_id = 0;

	rhs = (mxArray **)mxMalloc(sizeof(mxArray *)*NUM_OF_RETURN_FIELD);

	/* Parameters */
	rhs[out_id] = mxCreateDoubleMatrix(5, 1, mxREAL);
	ptr = mxGetPr(rhs[out_id]);
	ptr[0] = model->param.svm_type;
	ptr[1] = model->param.kernel_type;
	ptr[2] = model->param.degree;
	ptr[3] = model->param.gamma;
	ptr[4] = model->param.coef0;
	out_id++;

	/* nr_class */
	rhs[out_id] = mxCreateDoubleMatrix(1, 1, mxREAL);
	ptr = mxGetPr(rhs[out_id]);
	ptr[0] = model->nr_class;
	out_id++;

	/* total SV */
	rhs[out_id] = mxCreateDoubleMatrix(1, 1, mxREAL);
	ptr = mxGetPr(rhs[out_id]);
	ptr[0] = model->l;
	out_id++;

	/* rho */
	n = model->nr_class*(model->nr_class-1)/2;
	rhs[out_id] = mxCreateDoubleMatrix(n, 1, mxREAL);
	ptr = mxGetPr(rhs[out_id]);
	for(i = 0; i < n; i++)
		ptr[i] = model->rho[i];
	out_id++;

	/* Label */
	if(model->label)
	{
		rhs[out_id] = mxCreateDoubleMatrix(model->nr_class, 1, mxREAL);
		ptr = mxGetPr(rhs[out_id]);
		for(i = 0; i < model->nr_class; i++)
			ptr[i] = model->label[i];
	}
	else
		rhs[out_id] = mxCreateDoubleMatrix(0, 0, mxREAL);
	out_id++;

	/* probA */
	if(model->probA != NULL)
	{
		rhs[out_id] = mxCreateDoubleMatrix(n, 1, mxREAL);
		ptr = mxGetPr(rhs[out_id]);
		for(i = 0; i < n; i++)
			ptr[i] = model->probA[i];
	}
	else
		rhs[out_id] = mxCreateDoubleMatrix(0, 0, mxREAL);
	out_id ++;

	/* probB */
	if(model->probB != NULL)
	{
		rhs[out_id] = mxCreateDoubleMatrix(n, 1, mxREAL);
		ptr = mxGetPr(rhs[out_id]);
		for(i = 0; i < n; i++)
			ptr[i] = model->probB[i];
	}
	else
		rhs[out_id] = mxCreateDoubleMatrix(0, 0, mxREAL);
	out_id++;

	/* nSV */
	if(model->nSV)
	{
		rhs[out_id] = mxCreateDoubleMatrix(model->nr_class, 1, mxREAL);
		ptr = mxGetPr(rhs[out_id]);
		for(i = 0; i < model->nr_class; i++)
			ptr[i] = model->nSV[i];
	}
	else
		rhs[out_id] = mxCreateDoubleMatrix(0, 0, mxREAL);
	out_id++;

	/* sv_coef */
	rhs[out_id] = mxCreateDoubleMatrix(model->l, model->nr_class-1, mxREAL);
	ptr = mxGetPr(rhs[out_id]);
	for(i = 0; i < model->nr_class-1; i++)
		for(j = 0; j < model->l; j++)
			ptr[(i*(model->l))+j] = model->sv_coef[i][j];
	out_id++;

	/* SVs */
	{
		int ir_index, nonzero_element;
		mwIndex *ir, *jc;
		mxArray *pprhs[1], *pplhs[1];	

		if(model->param.kernel_type == PRECOMPUTED)
		{
			nonzero_element = model->l;
			num_of_feature = 1;
		}
		else
		{
			nonzero_element = 0;
			for(i = 0; i < model->l; i++) {
				j = 0;
				while(model->SV[i][j].index != -1) 
				{
					nonzero_element++;
					j++;
				}
			}
		}

		/* SV in column, easier accessing */
		rhs[out_id] = mxCreateSparse(num_of_feature, model->l, nonzero_element, mxREAL);
		ir = mxGetIr(rhs[out_id]);
		jc = mxGetJc(rhs[out_id]);
		ptr = mxGetPr(rhs[out_id]);
		jc[0] = ir_index = 0;		
		for(i = 0;i < model->l; i++)
		{
			if(model->param.kernel_type == PRECOMPUTED)
			{
				/* make a (1 x model->l) matrix */
				ir[ir_index] = 0; 
				ptr[ir_index] = model->SV[i][0].value;
				ir_index++;
				jc[i+1] = jc[i] + 1;
			}
			else
			{
				int x_index = 0;
				while (model->SV[i][x_index].index != -1)
				{
					ir[ir_index] = model->SV[i][x_index].index - 1; 
					ptr[ir_index] = model->SV[i][x_index].value;
					ir_index++, x_index++;
				}
				jc[i+1] = jc[i] + x_index;
			}
		}
		/* transpose back to SV in row */
		pprhs[0] = rhs[out_id];
		if(mexCallMATLAB(1, pplhs, 1, pprhs, "transpose"))
			return "cannot transpose SV matrix";
		rhs[out_id] = pplhs[0];
		out_id++;
	}

	/* Create a struct matrix contains NUM_OF_RETURN_FIELD fields */
	return_model = mxCreateStructMatrix(1, 1, NUM_OF_RETURN_FIELD, field_names);

	/* Fill struct matrix with input arguments */
	for(i = 0; i < NUM_OF_RETURN_FIELD; i++)
		mxSetField(return_model,0,field_names[i],mxDuplicateArray(rhs[i]));
	/* return */
	plhs[0] = return_model;
	mxFree(rhs);

	return NULL;
}
Exemplo n.º 23
0
void mexFunction (int nlhs, mxArray *plhs[],
                  int nrhs, const mxArray *prhs[])
{

    uint32_T *C, *A;
    mwIndex i,j, k, ik, middlek, *walkbuffer,jwalk, jwalkb, jwalka, new_front;
    mwSize n, m,*indegree;
    int *ancestors, ancestors_in_path, removed_ancestors, ncut, *newancestorbuff;
    double *Icut,*Jcut, *Icutp, *Jcutp;
    bool *visited, new_ancestor_flag, walkterminated, startwalk, cut_mode;
    
    if (nrhs != 1) 
        mexErrMsgTxt("Wrong number of input arguments");
    if ((nlhs > 1))
        mexErrMsgTxt("Wrong number of output arguments");
    

    n = mxGetN(A_IN);
    m = mxGetM(A_IN);
    if ((m!=1) && (n!=1))
        mexErrMsgTxt("Input must be a vector");
    if (mxGetClassID(A_IN) != mxUINT32_CLASS)
        mexErrMsgTxt("Input vector must be of type uint32");
   
    /* Create output */
    C_OUT = mxCreateNumericMatrix(m, n, mxUINT32_CLASS, mxREAL);
    if (C_OUT == NULL) 
         mexErrMsgTxt("Unsufficient memory");
    C = (uint32_T *) mxGetPr(C_OUT);   
    A = (uint32_T *) mxGetPr(A_IN);
    if (m>n)
        n = m;
    for (j=0; j<n; j++)
        C[j]= A[j];

    
    
    ancestors = mxMalloc(n*sizeof(int));
    indegree = mxMalloc((n+2)*sizeof(mwSize)); /* +2 for handling nodes with no neighbors */
    visited = mxMalloc(n*sizeof(bool));
    walkbuffer = mxMalloc(20*sizeof(mwIndex));
    newancestorbuff = mxMalloc(20*sizeof(int));
    if ((indegree == NULL) || (walkbuffer == NULL) || (visited == NULL) || (newancestorbuff==NULL))
        mexErrMsgTxt("Unsufficient memory");
  


    
    /* compute indegrees*/
    for (j=0; j< n; j++){
        indegree[j]  =(mwSize) 0; 
        ancestors[j] = (int) 0; 
        visited[j]=false;}

    
    for (j=0; j<n; j++)
            indegree[C[j]]=indegree[C[j]]+1;


    
    ncut=0;
    /* partition into clusters of small diameter */
    for (j=0; j<n; j++) {
        jwalk=j;
        startwalk=true;
        while (startwalk && (indegree[jwalk] == 0) && !visited[jwalk] && C[j]!=(n+1) ){
            startwalk=false;
            ancestors_in_path=1;
            k=0;
            walkbuffer[k]=jwalk;
            newancestorbuff[k]=0;
            while (k<=5 || visited[jwalk]){
                jwalk = C[jwalk];
                walkterminated=(jwalk == walkbuffer[k]) || ((k>0) && (jwalk == walkbuffer[k-1]));
                if (walkterminated)
                    break; /* while */
                k = k+1;
                walkbuffer[k] = jwalk;
                if (visited[jwalk]){
                    newancestorbuff[k] = ancestors_in_path;}
                else {
                    ancestors_in_path = ancestors_in_path+1;
                    newancestorbuff[k] = ancestors_in_path;}} 
            if (k>5){ /* large diamater - make cut */
                ncut=ncut+1;
                middlek = k/2;
                C[walkbuffer[middlek]]=walkbuffer[middlek];  /* cut middle edge */
                indegree[walkbuffer[middlek+1]]=indegree[walkbuffer[middlek+1]]-1; /* update indegree */
                for (ik=(middlek+1); ik<=k; ik++){
                    ancestors[walkbuffer[ik]] = ancestors[walkbuffer[ik]]-ancestors[walkbuffer[middlek]];}
                for (ik=0; ik<=middlek; ik++) {   /* update ancestors and visited flag */
                    visited[walkbuffer[ik]]=true;
                    ancestors[walkbuffer[ik]] = ancestors[walkbuffer[ik]]+newancestorbuff[ik];}
                jwalk = walkbuffer[middlek+1]; /* set first vertex in new walk */
                startwalk=true;} /* end cut procedure */
            if (!startwalk)
                for (ik=0; ik<=k; ik++){
                    ancestors[walkbuffer[ik]] = ancestors[walkbuffer[ik]]+newancestorbuff[ik];                    
                    visited[walkbuffer[ik]]=true;}}
    } 
    
    
        
    /* partition into clusters of high conductance */
    for (j=0; j<n; j++) {
        jwalk=j;
        startwalk=true;
        while (startwalk && (indegree[jwalk] == 0) && C[j]!=(n+1)){
            startwalk=false;            
            jwalkb=jwalk;
            cut_mode = false;
            while (true){
                jwalka = C[jwalk];
                walkterminated= ((jwalka == jwalk) || (jwalka == jwalkb));
                if (walkterminated)
                    break; /* while */

                if (!cut_mode && (ancestors[jwalk] >2) && ((ancestors[jwalka]-ancestors[jwalk])>2)) { /*low conductance - make cut*/
                    C[jwalk] = jwalk; /* cut edge */
                    ncut = ncut+1;
                    indegree[jwalka] = indegree[jwalka]-1;
                    removed_ancestors = ancestors[jwalk];
                    new_front = jwalka;
                    cut_mode = true;} /* end making cut */
                jwalkb = jwalk;
                jwalk = jwalka;
                if (cut_mode)
                    ancestors[jwalk] = ancestors[jwalk] -removed_ancestors;}
            if (cut_mode){
                startwalk=true;
                jwalk=new_front;}
        } 
    } 
    
       
        mxFree(indegree);
        mxFree(visited);
        mxFree(ancestors);
        mxFree(walkbuffer);
        mxFree(newancestorbuff);
        
}
Exemplo n.º 24
0
void
mexFunction(int nout, mxArray *out[],
            int nin, const mxArray *in[])
{
  int M,N,S,smin,K ;
  const int* dimensions ;
  const double* P_pt ;
  const double* D_pt ;
  double threshold = 0.01 ; /*0.02 ;*/
  double r = 10.0 ;
  double* result ;
  enum {IN_P=0,IN_D,IN_SMIN,IN_THRESHOLD,IN_R} ;
  enum {OUT_Q=0} ;

  /* -----------------------------------------------------------------
  **                                               Check the arguments
  ** -------------------------------------------------------------- */
  if (nin < 3) {
    mexErrMsgTxt("At least three input arguments required.");
  } else if (nout > 1) {
    mexErrMsgTxt("Too many output arguments.");
  }

  if( !uIsRealMatrix(in[IN_P],3,-1) ) {
    mexErrMsgTxt("P must be a 3xK real matrix") ;
  }

  if( !mxIsDouble(in[IN_D]) || mxGetNumberOfDimensions(in[IN_D]) != 3) {
    mexErrMsgTxt("G must be a three dimensional real array.") ;
  }

  if( !uIsRealScalar(in[IN_SMIN]) ) {
    mexErrMsgTxt("SMIN must be a real scalar.") ;
  }

  if(nin >= 4) {
    if(!uIsRealScalar(in[IN_THRESHOLD])) {
      mexErrMsgTxt("THRESHOLD must be a real scalar.") ;
    }
    threshold = *mxGetPr(in[IN_THRESHOLD]) ;
  }

  if(nin >= 5) {
    if(!uIsRealScalar(in[IN_R])) {
      mexErrMsgTxt("R must be a real scalar.") ;
    }
    r = *mxGetPr(in[IN_R]) ;
  }

  dimensions = mxGetDimensions(in[IN_D]) ;
  M = dimensions[0] ;
  N = dimensions[1] ;
  S = dimensions[2] ;
  smin = (int)(*mxGetPr(in[IN_SMIN])) ;

  if(S < 3 || M < 3 || N < 3) {
    mexErrMsgTxt("All dimensions of DOG must be not less than 3.") ;
  }

  K = mxGetN(in[IN_P]) ;
  P_pt = mxGetPr(in[IN_P]) ;
  D_pt = mxGetPr(in[IN_D]) ;

  /* If the input array is empty, then output an empty array as well. */
  if( K == 0) {
    out[OUT_Q] = mxDuplicateArray(in[IN_P]) ;
    return ;
  }

  /* -----------------------------------------------------------------
   *                                                        Do the job
   * -------------------------------------------------------------- */
  {
    double* buffer = (double*) mxMalloc(K*3*sizeof(double)) ;
    double* buffer_iterator = buffer ;
    int p ;
    const int yo = 1 ;
    const int xo = M ;
    const int so = M*N ;

    for(p = 0 ; p < K ; ++p) {
      int x = ((int)*P_pt++) ;
      int y = ((int)*P_pt++) ;
      int s = ((int)*P_pt++) - smin ;
      int iter ;
      double b[3] ;

      /* Local maxima extracted from the DOG
       * have coorrinates 1<=x<=N-2, 1<=y<=M-2
       * and 1<=s-mins<=S-2. This is also the range of the points
       * that we can refine.
       */
      if(x < 1 || x > N-2 ||
         y < 1 || y > M-2 ||
         s < 1 || s > S-2) {
        continue ;
      }

#define at(dx,dy,ds) (*(pt + (dx)*xo + (dy)*yo + (ds)*so))

      {
        const double* pt = D_pt + y*yo + x*xo + s*so ;
        double Dx=0,Dy=0,Ds=0,Dxx=0,Dyy=0,Dss=0,Dxy=0,Dxs=0,Dys=0 ;
        int dx = 0 ;
        int dy = 0 ;
        int j, i, jj, ii ;

        for(iter = 0 ; iter < max_iter ; ++iter) {

          double A[3*3] ;

#define Aat(i,j) (A[(i)+(j)*3])

          x += dx ;
          y += dy ;
          pt = D_pt + y*yo + x*xo + s*so ;

          /* Compute the gradient. */
          Dx = 0.5 * (at(+1,0,0) - at(-1,0,0)) ;
          Dy = 0.5 * (at(0,+1,0) - at(0,-1,0));
          Ds = 0.5 * (at(0,0,+1) - at(0,0,-1)) ;

          /* Compute the Hessian. */
          Dxx = (at(+1,0,0) + at(-1,0,0) - 2.0 * at(0,0,0)) ;
          Dyy = (at(0,+1,0) + at(0,-1,0) - 2.0 * at(0,0,0)) ;
          Dss = (at(0,0,+1) + at(0,0,-1) - 2.0 * at(0,0,0)) ;

          Dxy = 0.25 * ( at(+1,+1,0) + at(-1,-1,0) - at(-1,+1,0) - at(+1,-1,0) ) ;
          Dxs = 0.25 * ( at(+1,0,+1) + at(-1,0,-1) - at(-1,0,+1) - at(+1,0,-1) ) ;
          Dys = 0.25 * ( at(0,+1,+1) + at(0,-1,-1) - at(0,-1,+1) - at(0,+1,-1) ) ;

          /* Solve linear system. */
          Aat(0,0) = Dxx ;
          Aat(1,1) = Dyy ;
          Aat(2,2) = Dss ;
          Aat(0,1) = Aat(1,0) = Dxy ;
          Aat(0,2) = Aat(2,0) = Dxs ;
          Aat(1,2) = Aat(2,1) = Dys ;

          b[0] = - Dx ;
          b[1] = - Dy ;
          b[2] = - Ds ;

          /* Gauss elimination */
          for(j = 0 ; j < 3 ; ++j) {
            double maxa    = 0 ;
            double maxabsa = 0 ;
            int    maxi    = -1 ;
            double tmp ;

            /* look for the maximally stable pivot */
            for (i = j ; i < 3 ; ++i) {
              double a    = Aat (i,j) ;
              double absa = abs (a) ;
              if (absa > maxabsa) {
                maxa    = a ;
                maxabsa = absa ;
                maxi    = i ;
              }
            }

            /* if singular give up */
            if (maxabsa < 1e-10f) {
              b[0] = 0 ;
              b[1] = 0 ;
              b[2] = 0 ;
              break ;
            }

            i = maxi ;

            /* swap j-th row with i-th row and normalize j-th row */
            for(jj = j ; jj < 3 ; ++jj) {
              tmp = Aat(i,jj) ; Aat(i,jj) = Aat(j,jj) ; Aat(j,jj) = tmp ;
              Aat(j,jj) /= maxa ;
            }
            tmp = b[j] ; b[j] = b[i] ; b[i] = tmp ;
            b[j] /= maxa ;

            /* elimination */
            for (ii = j+1 ; ii < 3 ; ++ii) {
              double x = Aat(ii,j) ;
              for (jj = j ; jj < 3 ; ++jj) {
                Aat(ii,jj) -= x * Aat(j,jj) ;
              }
              b[ii] -= x * b[j] ;
            }
          }

          /* backward substitution */
          for (i = 2 ; i > 0 ; --i) {
            double x = b[i] ;
            for (ii = i-1 ; ii >= 0 ; --ii) {
              b[ii] -= x * Aat(ii,i) ;
            }
          }

          /* If the translation of the keypoint is big, move the keypoint
           * and re-iterate the computation. Otherwise we are all set.
           */
          dx= ((b[0] >  0.6 && x < N-2) ?  1 : 0 )
            + ((b[0] < -0.6 && x > 1  ) ? -1 : 0 ) ;

          dy= ((b[1] >  0.6 && y < M-2) ?  1 : 0 )
            + ((b[1] < -0.6 && y > 1  ) ? -1 : 0 ) ;

          if( dx == 0 && dy == 0 ) break ;

        }

        {
          double val = at(0,0,0) + 0.5 * (Dx * b[0] + Dy * b[1] + Ds * b[2]) ;
          double score = (Dxx+Dyy)*(Dxx+Dyy) / (Dxx*Dyy - Dxy*Dxy) ;
          double xn = x + b[0] ;
          double yn = y + b[1] ;
          double sn = s + b[2] ;

          if(fabs(val) > threshold &&
             score < (r+1)*(r+1)/r &&
             score >= 0 &&
             fabs(b[0]) < 1.5 &&
             fabs(b[1]) < 1.5 &&
             fabs(b[2]) < 1.5 &&
             xn >= 0 &&
             xn <= N-1 &&
             yn >= 0 &&
             yn <= M-1 &&
             sn >= 0 &&
             sn <= S-1) {
            *buffer_iterator++ = xn ;
            *buffer_iterator++ = yn ;
            *buffer_iterator++ = sn+smin  ;
          }
        }
      }
    }

    /* Copy the result into an array. */
    {
      int NL = (buffer_iterator - buffer)/3 ;
      out[OUT_Q] = mxCreateDoubleMatrix(3, NL, mxREAL) ;
      result = mxGetPr(out[OUT_Q]);
      memcpy(result, buffer, sizeof(double) * 3 * NL) ;
    }
    mxFree(buffer) ;
  }

}
Exemplo n.º 25
0
void mexFunction
(
    int nargout,
    mxArray *pargout[],
    int nargin,
    const mxArray *pargin[]
)
{
    Long b, n, i, k, j, *Ap, *Ai, *P, *R, nblocks, *Work, *Q, jj ;
    double *Px, *Rx, *Qx ;

    /* ---------------------------------------------------------------------- */
    /* get inputs and allocate workspace */
    /* ---------------------------------------------------------------------- */

    if (!((nargin == 1 && nargout <= 2) || (nargin == 2 && nargout <= 3)))
    {
        mexErrMsgTxt ("Usage: [p,r] = strongcomp (A)"
                      " or [p,q,r] = strongcomp (A,qin)") ;
    }
    n = mxGetM (pargin [0]) ;
    if (!mxIsSparse (pargin [0]) || n != mxGetN (pargin [0]))
    {
        mexErrMsgTxt ("strongcomp: A must be sparse, square, and non-empty") ;
    }

    /* get sparse matrix A */
    Ap = (Long *) mxGetJc (pargin [0]) ;
    Ai = (Long *) mxGetIr (pargin [0]) ;

    /* get output arrays */
    P = mxMalloc (n * sizeof (Long)) ;
    R = mxMalloc ((n+1) * sizeof (Long)) ;

    /* get workspace of size 4n (recursive code only needs 2n) */
    Work = mxMalloc (4*n * sizeof (Long)) ;

    /* get the input column permutation Q */
    if (nargin == 2)
    {
        if (mxGetNumberOfElements (pargin [1]) != n)
        {
            mexErrMsgTxt
                ("strongcomp: qin must be a permutation vector of size n") ;
        }
        Qx = mxGetPr (pargin [1]) ;
        Q = mxMalloc (n * sizeof (Long)) ;
        /* connvert Qin to 0-based and check validity */
        for (i = 0 ; i < n ; i++)
        {
            Work [i] = 0 ;
        }
        for (k = 0 ; k < n ; k++)
        {
            j = Qx [k] - 1 ;    /* convert to 0-based */
            jj = BTF_UNFLIP (j) ;
            if (jj < 0 || jj >= n || Work [jj] == 1)
            {
                mexErrMsgTxt
                    ("strongcomp: qin must be a permutation vector of size n") ;
            }
            Work [jj] = 1 ;
            Q [k] = j ;
        }
    }
    else
    {
        /* no input column permutation */
        Q = (Long *) NULL ;
    }

    /* ---------------------------------------------------------------------- */
    /* find the strongly-connected components of A */
    /* ---------------------------------------------------------------------- */

    nblocks = btf_l_strongcomp (n, Ap, Ai, Q, P, R, Work) ;

    /* ---------------------------------------------------------------------- */
    /* create outputs and free workspace */
    /* ---------------------------------------------------------------------- */

    /* create P */
    pargout [0] = mxCreateDoubleMatrix (1, n, mxREAL) ;
    Px = mxGetPr (pargout [0]) ;
    for (k = 0 ; k < n ; k++)
    {
        Px [k] = P [k] + 1 ;            /* convert to 1-based */
    }

    /* create Q */
    if (nargin == 2 && nargout > 1)
    {
        pargout [1] = mxCreateDoubleMatrix (1, n, mxREAL) ;
        Qx = mxGetPr (pargout [1]) ;
        for (k = 0 ; k < n ; k++)
        {
            Qx [k] = Q [k] + 1 ;        /* convert to 1-based */
        }
    }

    /* create R */
    if (nargout == nargin + 1)
    {
        pargout [nargin] = mxCreateDoubleMatrix (1, nblocks+1, mxREAL) ;
        Rx = mxGetPr (pargout [nargin]) ;
        for (b = 0 ; b <= nblocks ; b++)
        {
            Rx [b] = R [b] + 1 ;                /* convert to 1-based */
        }
    }

    mxFree (P) ;
    mxFree (R) ;
    mxFree (Work) ;
    if (nargin == 2)
    {
        mxFree (Q) ;
    }
}
Exemplo n.º 26
0
/* The gateway function */
void mexFunction( int nlhs, mxArray *plhs[],
                  int nrhs, const mxArray *prhs[])
{
    /* check for proper number of arguments */
    if(nrhs != 1) {
        mexErrMsgIdAndTxt("HDRToolbox:write_exr:nrhs", "One input is required.");
    }
    
    char *nameFile;
    mwSize buflen;
    int status;    
    buflen = mxGetN(prhs[0])*sizeof(mxChar)+1;
    nameFile = (char*) mxMalloc(buflen);
    
    /* Copy the string data into buf. */ 
    status = mxGetString(prhs[0], nameFile, buflen);
    

    
    /* call the computational routine */
    EXRImage image;
    InitEXRImage(&image);

    const char* err;
    int ret = ParseMultiChannelEXRHeaderFromFile(&image, nameFile, &err);
    if (ret != 0) {
        printf("Parse EXR error: %s\n", err);
        return;
    }

    int width = image.width;
    int height = image.height;
    int channels = image.num_channels;

    //Allocate into memory

    mwSize dims[3];
    dims[0] = height;
    dims[1] = width;
    dims[2] = channels;

    plhs[0] = mxCreateNumericArray(channels, dims, mxDOUBLE_CLASS, mxREAL);
    double *outMatrix = mxGetPr(plhs[0]);

    for (int i = 0; i < image.num_channels; i++) {
        if (image.pixel_types[i] == TINYEXR_PIXELTYPE_HALF) {
            image.requested_pixel_types[i] = TINYEXR_PIXELTYPE_FLOAT;
        }
    }
    
    ret = LoadMultiChannelEXRFromFile(&image, nameFile, &err);
    
    if (ret != 0) {
        printf("Load EXR error: %s\n", err);
        return;
    }
    
    float **images = (float**) image.images;
    int nPixels = width * height;
    int nPixels2 = nPixels * 2;
    if(channels == 1) {
        nPixels = 0;
        nPixels2 = 0;
    }
    
    if(channels == 2) {
        nPixels2 = 0;
    }
    
    for (int i = 0; i < width; i++){
        for (int j = 0; j < height; j++){
            int index = i * height + j;
            int indexOut = j * width + i;
            
            outMatrix[index    ]        = images[2][indexOut];
            outMatrix[index + nPixels]  = images[1][indexOut];
            outMatrix[index + nPixels2] = images[0][indexOut];
        }
    }
    
    
}
Exemplo n.º 27
0
void mexFunction(
                 int nlhs,       mxArray *plhs[],
                 int nrhs, const mxArray *prhs[])
{

  
  // ovals - struct, the structure containing the ovals
  if(nlhs != 0 || nrhs != 0)
    mexErrMsgTxt("Error this function takes and returns no arguments");

  const mxArray* pmxBeta = mexGetArrayPtr("BETA", "global");
  double*  beta = mxGetPr(pmxBeta);
  const mxArray* pmxNdata = mexGetArrayPtr("NDATA", "global");
  int nData = (int)*mxGetPr(pmxNdata);
  const mxArray* pmxDataDim = mexGetArrayPtr("DATADIM", "global");
  int dataDim = (int)*mxGetPr(pmxDataDim);
  const mxArray* pmxLatentDim = mexGetArrayPtr("LATENTDIM", "global");
  int latentDim = (int)*mxGetPr(pmxLatentDim);
  const mxArray* pmxX = mexGetArrayPtr("X", "global");
  double* X = mxGetPr(pmxX);
  const mxArray* pmxA = mexGetArrayPtr("A", "global");
  double* A = mxGetPr(pmxA);
  const mxArray* pmxSBar = mexGetArrayPtr("SBAR", "global");
  double* sBar = mxGetPr(pmxSBar);
  const mxArray* pmxSigma_s = mexGetArrayPtr("SIGMA_S", "global");
  double* Sigma_s = mxGetPr(pmxSigma_s);
  const mxArray* pmxFANoise = mexGetArrayPtr("FANOISE", "global");
  int FANoise = (int)*mxGetPr(pmxFANoise);
  const mxArray* pmxTau = mexGetArrayPtr("TAU", "global");
  double* tau = mxGetPr(pmxTau);


//for n = 1:NDATA
//end
  int lda = latentDim;
  int length = latentDim;
  int info = 0;
  int* ipiv = (int*)mxMalloc(length*sizeof(int));
  int order = latentDim;
  int lwork = order*16;
  double* work = (double*)mxMalloc(lwork*sizeof(double));

  for(int n = 0; n < nData; n++) {
    //   invSigma_s = diag(TAU(n, :)) + ATBA;
    for(int j = 0; j < latentDim; j++) {
      for(int j2 = 0; j2 < latentDim; j2++) {
        if(j2==j) {
          // Add the diagonal term
          Sigma_s[j + j2*latentDim + n*latentDim*latentDim] = tau[n + j*nData];
        }
        else {
          Sigma_s[j + j2*latentDim + n*latentDim*latentDim] = 0;
        }
        double temp = 0;
        if (FANoise != 0){
          for(int i = 0; i < dataDim; i++) {
            temp += A[i + j2*dataDim]*A[i + j*dataDim]*beta[i];
          }
        }
        else {
          for(int i = 0; i < dataDim; i++) {
            temp += A[i + j2*dataDim]*A[i + j*dataDim];
          }
          temp *= beta[0];		
        }
        // This is really inv(Sigma_s) but it is stored here for convenience
		Sigma_s[j + j2*latentDim + n*latentDim*latentDim] += temp;
      }
    }
    
    // It is not being done by cholesky decomposition in the c++ code
    // but it should be
    // C = chol(invSigma_s);
    // Cinv = eye(LATENTDIM)/C;
    // SIGMA_S(:, :, n) = Cinv*Cinv'; 
    
    // create inverse first by lu decomposition of input    
    
    // call lapack
    dgetrf(latentDim, latentDim, 
            Sigma_s+n*latentDim*latentDim, lda, ipiv, info);
    if(info != 0)
      mexErrMsgTxt("Problems in lu factorisation of matrix");
    
    info = 0;
    // peform the matrix inversion.
    dgetri(order, Sigma_s+n*latentDim*latentDim, lda, 
            ipiv, work, lwork, info);
    // check for successfull inverse
    if(info > 0)
      mexErrMsgTxt("Matrix is singular");
    else if(info < 0)
      mexErrMsgTxt("Problem in matrix inverse");
    
    
    // SBAR(n, :) = (X(n, :).*BETA)*A*SIGMA_S(:, :, n);
    
    if(FANoise != 0) {
      for(int j = 0; j < latentDim; j++) {
        sBar[n + j*nData] = 0;
        for(int j2 = 0; j2 < latentDim; j2++) {
          for(int i = 0; i < dataDim; i++) {
            sBar[n + j*nData] += X[n + i*nData]*beta[i]*A[i + j2*dataDim]*Sigma_s[j + j2*latentDim + n*latentDim*latentDim];  
          }
        }
      }
    }
    else {
      for(int j = 0; j < latentDim; j++) {
        sBar[n + j*nData] = 0;
        for(int j2 = 0; j2 < latentDim; j2++) {
          for(int i = 0; i < dataDim; i++) {
            sBar[n + j*nData] += X[n + i*nData]*beta[0]*A[i + j2*dataDim]*Sigma_s[j + j2*latentDim + n*latentDim*latentDim];  
          }
        }
      }
    }
  }
  mxFree(work);
  mxFree(ipiv);

}
Exemplo n.º 28
0
void mexFunction
(
    int	nargout,
    mxArray *pargout[ ],
    int	nargin,
    const mxArray *pargin[ ]
)
{
    UF_long i, n, *Pattern, *Flag, *Li, *Lp, *Ap, *Ai, *Lnz, *Parent, do_chol,
	nrhs = 0, lnz, do_solve, *P, *Pinv, nn, k, j, permute, *Dp = NULL, *Di,
	d, do_flops, psrc, pdst ;
    double *Y, *D, *Lx, *Ax, flops, *X = NULL, *B = NULL, *p ;

    /* ---------------------------------------------------------------------- */
    /* get inputs and allocate workspace */
    /* ---------------------------------------------------------------------- */

    do_chol  = (nargin > 0) && (nargin <= 2) && (nargout <= 4) ;
    do_solve = (nargin == 3) && (nargout <= 2) ;
    if (!(do_chol || do_solve))
    {
	mexErrMsgTxt ("Usage:\n"
	    "  [L, D, etree, flopcount] = ldl (A) ;\n"
	    "  [L, D, etree, flopcount] = ldl (A, P) ;\n"
	    "  [x, flopcount] = ldl (A, [ ], b) ;\n"
	    "  [x, flopcount] = ldl (A, P, b) ;\n"
	    "The etree and flopcount arguments are optional.") ;
    }
    n = mxGetM (pargin [0]) ;
    if (!mxIsSparse (pargin [0]) || n != mxGetN (pargin [0])
	    || mxIsComplex (pargin [0]))
    {
    	mexErrMsgTxt ("ldl: A must be sparse, square, and real") ;
    }
    if (do_solve)
    {
	if (mxIsSparse (pargin [2]) || n != mxGetM (pargin [2])
	    || !mxIsDouble (pargin [2]) || mxIsComplex (pargin [2]))
	{
	    mexErrMsgTxt (
		"ldl: b must be dense, real, and with proper dimension") ;
	}
    }
    nn = (n == 0) ? 1 : n ;

    /* get sparse matrix A */
    Ap = (UF_long *) mxGetJc (pargin [0]) ;
    Ai = (UF_long *) mxGetIr (pargin [0]) ;
    Ax = mxGetPr (pargin [0]) ;

    /* get fill-reducing ordering, if present */
    permute = ((nargin > 1) && !mxIsEmpty (pargin [1])) ;
    if (permute)
    {
	if (mxGetM (pargin [1]) * mxGetN (pargin [1]) != n ||
		mxIsSparse (pargin [1]))
	{
	    mexErrMsgTxt ("ldl: invalid input permutation\n") ;
	}
	P    = (UF_long *) mxMalloc (nn * sizeof (UF_long)) ;
	Pinv = (UF_long *) mxMalloc (nn * sizeof (UF_long)) ;
	p = mxGetPr (pargin [1]) ;
	for (k = 0 ; k < n ; k++)
	{
	    P [k] = p [k] - 1 ;	/* convert to 0-based */
	}
    }
    else
    {
	P    = (UF_long *) NULL ;
	Pinv = (UF_long *) NULL ;
    }

    /* allocate first part of L */
    Lp      = (UF_long *) mxMalloc ((n+1) * sizeof (UF_long)) ;
    Parent  = (UF_long *) mxMalloc (nn * sizeof (UF_long)) ;

    /* get workspace */
    Y       = (double *)  mxMalloc (nn * sizeof (double)) ;
    Flag    = (UF_long *) mxMalloc (nn * sizeof (UF_long)) ;
    Pattern = (UF_long *) mxMalloc (nn * sizeof (UF_long)) ;
    Lnz     = (UF_long *) mxMalloc (nn * sizeof (UF_long)) ;

    /* make sure the input P is valid */
    if (permute && !ldl_l_valid_perm (n, P, Flag))
    {
	mexErrMsgTxt ("ldl: invalid input permutation\n") ;
    }

    /* note that we assume that the input matrix is valid */

    /* ---------------------------------------------------------------------- */
    /* symbolic factorization to get Lp, Parent, Lnz, and optionally Pinv */
    /* ---------------------------------------------------------------------- */

    ldl_l_symbolic (n, Ap, Ai, Lp, Parent, Lnz, Flag, P, Pinv) ;
    lnz = Lp [n] ;

    /* ---------------------------------------------------------------------- */
    /* create outputs */
    /* ---------------------------------------------------------------------- */

    if (do_chol)
    {
	/* create the output matrix L, using the Lp array from ldl_l_symbolic */
	pargout [0] = mxCreateSparse (n, n, lnz+1, mxREAL) ;
	mxFree (mxGetJc (pargout [0])) ;
	mxSetJc (pargout [0], (void *) Lp) ;	/* Lp is not mxFree'd */
	Li = (UF_long *) mxGetIr (pargout [0]) ;
	Lx = mxGetPr (pargout [0]) ;

	/* create sparse diagonal matrix D */
	if (nargout > 1)
	{
	    pargout [1] = mxCreateSparse (n, n, nn, mxREAL) ;
	    Dp = (UF_long *) mxGetJc (pargout [1]) ;
	    Di = (UF_long *) mxGetIr (pargout [1]) ;
	    for (j = 0 ; j < n ; j++)
	    {
		Dp [j] = j ;
		Di [j] = j ;
	    }
	    Dp [n] = n ;
	    D = mxGetPr (pargout [1])  ;
	}
	else
	{
	    D  = (double *) mxMalloc (nn * sizeof (double)) ;
	}

	/* return elimination tree (add 1 to change from 0-based to 1-based) */
	if (nargout > 2)
	{
	    pargout [2] = mxCreateDoubleMatrix (1, n, mxREAL) ;
	    p = mxGetPr (pargout [2]) ;
	    for (i = 0 ; i < n ; i++)
	    {
		p [i] = Parent [i] + 1 ;
	    }
	}

	do_flops = (nargout == 4) ? (3) : (-1) ;
    }
    else
    {
	/* create L and D as temporary matrices */
	Li = (UF_long *)    mxMalloc ((lnz+1) * sizeof (UF_long)) ;
	Lx = (double *) mxMalloc ((lnz+1) * sizeof (double)) ;
	D  = (double *) mxMalloc (nn * sizeof (double)) ;

	/* create solution x */
	nrhs = mxGetN (pargin [2]) ;
	pargout [0] = mxCreateDoubleMatrix (n, nrhs, mxREAL) ;
	X = mxGetPr (pargout [0]) ;
	B = mxGetPr (pargin [2]) ;

	do_flops = (nargout == 2) ? (1) : (-1) ;
    }

    if (do_flops >= 0)
    {
	/* find flop count for ldl_l_numeric */
	flops = 0 ;
	for (k = 0 ; k < n ; k++)
	{
	    flops += ((double) Lnz [k]) * (Lnz [k] + 2) ;
	}
	if (do_solve)
	{
	    /* add flop count for solve */
	    for (k = 0 ; k < n ; k++)
	    {
		flops += 4 * ((double) Lnz [k]) + 1 ;
	    }
	}
	pargout [do_flops] = mxCreateDoubleMatrix (1, 1, mxREAL) ;
	p = mxGetPr (pargout [do_flops]) ;
	p [0] = flops ;
    }

    /* ---------------------------------------------------------------------- */
    /* numeric factorization to get Li, Lx, and D */
    /* ---------------------------------------------------------------------- */

    d = ldl_l_numeric (n, Ap, Ai, Ax, Lp, Parent, Lnz, Li, Lx, D, Y, Flag,
	Pattern, P, Pinv) ;

    /* ---------------------------------------------------------------------- */
    /* singular case : truncate the factorization */
    /* ---------------------------------------------------------------------- */

    if (d != n)
    {
	/* D [d] is zero:  report error, or clean up */
	if (do_chol && do_flops < 0)
	{
	    mexErrMsgTxt ("ldl: zero pivot encountered\n") ;
	}
	else
	{
	    /* L and D are incomplete, compact them */
	    if (do_chol)
	    {
		for (k = d ; k < n ; k++)
		{
		    Dp [k] = d ;
		}
		Dp [n] = d ;
	    }
	    for (k = d ; k < n ; k++)
	    {
		D [k] = 0 ;
	    }
	    pdst = 0 ;
	    for (k = 0 ; k < d ; k++)
	    {
		for (psrc = Lp [k] ; psrc < Lp [k] + Lnz [k] ; psrc++)
		{
		    Li [pdst] = Li [psrc] ;
		    Lx [pdst] = Lx [psrc] ;
		    pdst++ ;
		}
	    }
	    for (k = 0 ; k < d  ; k++)
	    {
		Lp [k+1] = Lp [k] + Lnz [k] ;
	    }
	    for (k = d ; k <= n ; k++)
	    {
		Lp [k] = pdst ;
	    }
	    if (do_flops >= 0)
	    {
		/* return -d instead of the flop count (convert to 1-based) */
		p = mxGetPr (pargout [do_flops]) ;
		p [0] = -(1+d) ;
	    }
	}
    }

    /* ---------------------------------------------------------------------- */
    /* solve Ax=b, if requested */
    /* ---------------------------------------------------------------------- */

    if (do_solve)
    {
	if (permute)
	{
	    for (j = 0 ; j < nrhs ; j++)
	    {
		ldl_l_perm (n, Y, B, P) ;		    /* y = Pb */
		ldl_l_lsolve (n, Y, Lp, Li, Lx) ;	    /* y = L\y */
		ldl_l_dsolve (n, Y, D) ;		    /* y = D\y */
		ldl_l_ltsolve (n, Y, Lp, Li, Lx) ;	    /* y = L'\y */
		ldl_l_permt (n, X, Y, P) ;		    /* x = P'y */
		X += n ;
		B += n ;
	    }
	}
	else
	{
	    for (j = 0 ; j < nrhs ; j++)
	    {
		for (k = 0 ; k < n ; k++)		    /* x = b */
		{
		    X [k] = B [k] ;
		}
		ldl_l_lsolve (n, X, Lp, Li, Lx) ;	    /* x = L\x */
		ldl_l_dsolve (n, X, D) ;		    /* x = D\x */
		ldl_l_ltsolve (n, X, Lp, Li, Lx) ;	    /* x = L'\x */
		X += n ;
		B += n ;
	    }
	}
	/* free the matrix L */
	mxFree (Lp) ;
	mxFree (Li) ;
	mxFree (Lx) ;
	mxFree (D) ;
    }

    /* ---------------------------------------------------------------------- */
    /* free workspace */
    /* ---------------------------------------------------------------------- */

    if (do_chol && nargout < 2)
    {
	mxFree (D) ;
    }
    if (permute)
    {
	mxFree (P) ;
	mxFree (Pinv) ;
    }
    mxFree (Parent) ;
    mxFree (Y) ;
    mxFree (Flag) ;
    mxFree (Pattern) ;
    mxFree (Lnz) ;
}
void mexFunction(int nlhs,				// Number of left hand side (output) arguments
				 mxArray *plhs[],		// Array of left hand side arguments
				 int nrhs,              // Number of right hand side (input) arguments
				 const mxArray *prhs[])  // Array of right hand side arguments
{

  //check for proper number of arguments 
 
  if(nrhs != 4) mexErrMsgTxt("4 inputs required.");
  if(nlhs != 6) mexErrMsgTxt("6 outputs required.");

   //////////////////////////////////////////////////////////////
  // Input arguments
  //////////////////////////////////////////////////////////////
  
  // d
  int argu = 0;
  if( !mxIsDouble(prhs[argu]) || mxIsComplex(prhs[argu]) || mxGetN(prhs[argu])*mxGetM(prhs[argu])!=1 ) 
    mexErrMsgTxt("Input 'd' must be a scalar.");
  int d = (int)
    mxGetScalar(prhs[argu]);
  if (d <= 0) 
    mexErrMsgTxt("Input 'd' must be a positive number.");

  // N
  argu++;
  if( !mxIsDouble(prhs[argu]) || mxIsComplex(prhs[argu]) || mxGetN(prhs[argu])*mxGetM(prhs[argu])!=1 ) 
    mexErrMsgTxt("Input 'N' must be a scalar.");
  int N = (int) mxGetScalar(prhs[argu]);
  if (N <= 0) 
    mexErrMsgTxt("Input 'N' must be a positive number.");

  // x
  argu++;
  double *x = mxGetPr(prhs[argu]);
  int mrows = (int)mxGetM(prhs[argu]); //mrows
  int ncols = (int)mxGetN(prhs[argu]); //ncols
  if ( mrows != d && ncols != N )  
    mexErrMsgTxt("Input 'x' must be a d x N matrix.");
  
  // kMax
  argu++;
  if( !mxIsDouble(prhs[argu]) || mxIsComplex(prhs[argu]) || mxGetN(prhs[argu])*mxGetM(prhs[argu])!=1 ) 
    mexErrMsgTxt("Input 'kMax' must be a scalar.");
  int kMax = (int) mxGetScalar(prhs[argu]);
  if (kMax <= 0) 
    mexErrMsgTxt("Input 'kMax' must be a positive number.");

  //////////////////////////////////////////////////////////////
  // Output arguments
  //////////////////////////////////////////////////////////////

  // K
  argu = 0;
  plhs[argu] = mxCreateDoubleMatrix(1, 1, mxREAL );
  double * K = (double*)mxGetPr(plhs[argu]);

  // rx
  argu++;
  plhs[argu] = mxCreateDoubleMatrix(1, 1, mxREAL);
  double * rx = (double*)mxGetPr(plhs[argu]);
  
  // clusterIndex
  argu++;
  plhs[argu] = mxCreateNumericMatrix(1, N, mxUINT32_CLASS, mxREAL);
  int * clusterIndex = (int*)mxGetPr(plhs[argu]);

  int kTemp; 
  int * numPointsTemp = (int*)mxMalloc( sizeof(int)*kMax );
  double * clusterCentersTemp = (double*)mxMalloc( sizeof(double)*kMax*d );
  double * clusterRadiiTemp = (double*)mxMalloc( sizeof(double)*kMax );

  // function call
  figtreeKCenterClustering( d, N, x, kMax, &kTemp, rx, clusterIndex, clusterCentersTemp, numPointsTemp, clusterRadiiTemp );
  *K = kTemp;

  // The sizes of these arrays depend on the number of final clusters, which can be less than kMax. 
  // clusterCenters  
  argu++;
  plhs[argu] = mxCreateDoubleMatrix(d, kTemp, mxREAL);
  double * clusterCenters = mxGetPr(plhs[argu]);
  memcpy( clusterCenters, clusterCentersTemp, sizeof(double)*kTemp*d );

  // numPoints
  argu++;
  plhs[argu] = mxCreateNumericMatrix(1, kTemp, mxUINT32_CLASS, mxREAL);
  int * numPoints = (int*)mxGetPr(plhs[argu]);
  memcpy( numPoints, numPointsTemp, sizeof(int)*kTemp );

  // clusterRadii
  argu++;
  plhs[argu] = mxCreateDoubleMatrix(1, kTemp, mxREAL);
  double * clusterRadii = mxGetPr(plhs[argu]);
  memcpy( clusterRadii, clusterRadiiTemp, sizeof(double)*kTemp );

  // free temporary arrays
  mxFree( clusterCentersTemp );
  mxFree( numPointsTemp );
  mxFree( clusterRadiiTemp );

  return;
  
}
Exemplo n.º 30
0
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) 
{

/* deal with the underscores now so that they can be ignored after this point */
#ifdef WINDOWS
    double (*my_ddot)( int *, double *, int *, double *, int *) = ddot;
    complex16 (*my_zdot)( int *, complex16 *, int *, complex16 *, int *) = zdotu;
    void (*my_dgemm)(char *, char *, int *, int *, int *, double *, double *,
            int *, double *, int *, double *, double *, int *) = dgemm;
    void (*my_zgemm)(char *, char *, int *, int *, int *, complex16 *, complex16 *,
        int *, complex16 *, int *, complex16 *, complex16 *, int *) = zgemm;
#else
    double (*my_ddot)( int *, double *, int *, double *, int *) = ddot_;
    complex16 (*my_zdot)( int *, complex16 *, int *, complex16 *, int *) = zdotu_;
    void (*my_dgemm)(char *, char *, int *, int *, int *, double *, double *,
            int *, double *, int *, double *, double *, int *) = dgemm_;
    void (*my_zgemm)(char *, char *, int *, int *, int *, complex16 *, complex16 *,
            int *, complex16 *, int *, complex16 *, complex16 *, int *) = zgemm_;
#endif

    mwSize M, N, K, K2;
    mwSize nOmega1, nOmega2, nOmega;
    mwIndex i,j,k,m;
    double *U, *V, *output, *outputBLAS;
    double *U_imag, *V_imag, *output_imag; /* for complex data */
    complex16 *U_cplx, *V_cplx, temp_cplx; /* for complex data */
    double *omega, *omegaX, *omegaY;
    mwIndex *omegaI, *omegaJ;  /* for sparse version */
    int SPARSE = false;
    int COMPLEX = false;
    int USE_BLAS = false;
    int LARGE_BIT = false;
    int MODE_THREE = false;
    complex16 alpha_cplx, beta_cplx;
    complex16 *output_cplx;

    int one = 1;

    char transA = 'N', transB = 'T';
    mwSize LDA, LDB;
    double alpha, beta;
    double BLAS_CUTOFF;
    
    /* Check for proper number of input and output arguments */    
    if ( (nrhs < 3) || (nrhs > 5) ) {
        printUsage();
        mexErrMsgTxt("Three to five input argument required.");
    } 
    if(nlhs > 1){
        printUsage();
        mexErrMsgTxt("Too many output arguments.");
    }
    
    /* Check data type of input argument  */
    if (!(mxIsDouble(prhs[0])) || !((mxIsDouble(prhs[1]))) ){
        printUsage();
        mexErrMsgTxt("Input arguments wrong data-type (must be doubles).");
    }   

    /* Get the size and pointers to input data */
    /* TRANSPOSE VERSION: switch mxGetM and mxGetN */
    M  = mxGetN(prhs[0]);
    K  = mxGetM(prhs[0]);
    N  = mxGetN(prhs[1]);
    K2  = mxGetM(prhs[1]);
    if ( K != K2 ) {
        printUsage();
        mexErrMsgTxt("Inner dimension of U and V' must agree.");
    }
    COMPLEX = (( (mxIsComplex(prhs[0])) ) || (mxIsComplex(prhs[1])) );
    nOmega1 = mxGetM( prhs[2] );
    nOmega2 = mxGetN( prhs[2] );


    /* on 64-bit systems, these may be longs, but I really want
     * them to be ints so that they work with the BLAS calls */
    mxAssert(M<INT_MAX,"Matrix is too large for 32-bit FORTRAN");
    mxAssert(N<INT_MAX,"Matrix is too large for 32-bit FORTRAN");
    mxAssert(K<INT_MAX,"Matrix is too large for 32-bit FORTRAN");
    
    
    if ( (nOmega1 != 1) && (nOmega2 != 1) ) {
/*         mexErrMsgTxt("Omega must be a vector"); */
        /* Update:
         * if this happens, we assume Omega is really a sparse matrix
         * and everything is OK */
        if ( ( nOmega1 != M ) || ( nOmega2 != N ) || (!mxIsSparse( prhs[2] )) ){
            printUsage();
            mexErrMsgTxt("Omega must be a vector or a sparse matrix");
        }
        nOmega = mxGetNzmax( prhs[2] );
        SPARSE = true;
    } else {
        nOmega = nOmega1 < nOmega2 ? nOmega2 : nOmega1;
        if ( nOmega > N*M ) {
            printUsage();
            mexErrMsgTxt("Omega must have M*N or fewer entries");
        }
    }

    U = mxGetPr(prhs[0]);
    V = mxGetPr(prhs[1]);
    if (COMPLEX) {
        U_imag = mxGetPi(prhs[0]);
        V_imag = mxGetPi(prhs[1]);
        plhs[0] = mxCreateDoubleMatrix(nOmega, 1, mxCOMPLEX);
        output = mxGetPr(plhs[0]);
        output_imag = mxGetPi(plhs[0]);

        U_cplx = (complex16 *)mxMalloc( M*K*sizeof(complex16) );
        V_cplx = (complex16 *)mxMalloc( N*K*sizeof(complex16) );
        if ( (U_cplx == NULL) || ( V_cplx == NULL ) ) {
            /* this should be very rare */
            mexErrMsgTxt("Unable to allocate memory.  Matrix too large?");
        }
        

        for ( i=0 ; i < M*K ; i++ ){
            U_cplx[i].re = (double)U[i];
            U_cplx[i].im = (double)U_imag[i];
        }
        for ( i=0 ; i < N*K ; i++ ){
            V_cplx[i].re = (double)V[i];
            V_cplx[i].im = -(double)V_imag[i]; 
            /* minus sign, since adjoint, not transpose */
        }
        
    } else {
        plhs[0] = mxCreateDoubleMatrix(nOmega, 1, mxREAL);
        /* mxCreateDoubleMatrix automatically zeros out the entries */
        output = mxGetPr(plhs[0]);
    }

    /* Check for the optional input argument that specifies the cutoff
     * for level-3 BLAS */
    BLAS_CUTOFF = 0.4;  
    MODE_THREE = false;
    if ( nrhs > 4 ) {
        BLAS_CUTOFF = (double)*mxGetPr( prhs[4] );
        MODE_THREE = true;
    } else if (nrhs > 3 ) {
        /* decide if this third argument is BLAS_CUTOFF,
         * or omegaX */
        nOmega1 = mxGetM( prhs[3] );
        nOmega2 = mxGetN( prhs[3] );
        if ( (nOmega1 == 1) && (nOmega2 == 1) ) {
            BLAS_CUTOFF = (double)*mxGetPr( prhs[3] );
            MODE_THREE = false;
        } else {
            MODE_THREE = true;
        }
    }
    /* Decide if we'll make a level-3 BLAS call */
    USE_BLAS = ( nOmega >= BLAS_CUTOFF * (M*N) );



    /* 
     * We have 3 "modes":
     * Mode 1 
     *      if omega is a vector of linear indices
     * Mode 2
     *      if omega is given only by the nonzero elements of an input 
     *      sparse matrix Y
     * Mode 3
     *      if omega is given as a set of subscripts, i.e. omegaX, omegaY
     *      then the "for" loop is slightly different
     *
     *  October 29, 2009: changing this a bit.
     *      For any of the modes, we first check if length(omega) > .8*M*N
     *      If so, we make a level-3 BLAS call (dgemm), and then use this
     *      matrix as needed.
     *      
     */


    /* determine if we're on a 64-bit processor */
    LARGE_BIT = ( sizeof( size_t ) > 4 );



    if ( USE_BLAS ) {
        /* we need to compute A itself, so use level-3 BLAS */
        /* TRANSPOSE VERSION: switch N and T below, and change the step size and LDA */
        /*
        transA = 'N';
        transB = 'T';
        LDA = M;
        LDB = N; */
        transA = 'T';
        transB = 'N';
        LDA = K;
        LDB = K;

        if (COMPLEX) {
            alpha_cplx.re = 1.0;  alpha_cplx.im = 0.0;
            beta_cplx.re = 0.0;   beta_cplx.im  = 0.0;
            /* need to make a new complex data structure */
            output_cplx = (complex16 *) mxMalloc( M*N*sizeof(complex16) );
            if ( output_cplx == NULL ) {
                /* we don't have enough RAM available */
                USE_BLAS = false;
            } else {
                my_zgemm(&transA,&transB,(int*)&M,(int*)&N,(int*)&K,
                    &alpha_cplx,U_cplx,(int*)&LDA,V_cplx,(int*)&LDB,&beta_cplx,output_cplx,(int *)&M );
            }
        } else {
            outputBLAS = (double *)mxMalloc( M*N*sizeof(double) );
            if ( outputBLAS == NULL ) {
                /* we don't have enough RAM available */
                USE_BLAS = false;
            } else {
                alpha = 1.0;
                beta = 0.0;
                my_dgemm(&transA,&transB,(int*)&M,(int*)&N,(int*)&K,
                        &alpha,U,(int*)&LDA,V,(int*)&LDB,&beta,outputBLAS,(int*)&M );
            }
        }
    }



    /* --- MODE 1 ---*/
    if ( (!MODE_THREE) && (!SPARSE) ) {
         /* by default, make output the same shape (i.e. row- or column-
          * vector) as the input "omega" */
        mxSetM( plhs[0], mxGetM( prhs[2] ) );
        mxSetN( plhs[0], mxGetN( prhs[2] ) );
        omega = mxGetPr(prhs[2]);

        if ( !USE_BLAS ) {
            
            if ( (COMPLEX) && (LARGE_BIT) ) {
              /* TRANSPOSE VERSION: this needs to be tested!!! */
              for ( k=0 ; k < nOmega ; k++ ){
                i = (mwIndex) ( (mwIndex)(omega[k]-1) % M);
                j = (mwIndex) ( (mwIndex)(omega[k]-1)/ M);
                
                /* implement the BLAS call myself, since BLAS isn't working for me
                 * ZDOTU(N,ZX,INCX,ZY,INCY)  
                 * */
                temp_cplx.re = 0.0;
                temp_cplx.im = 0.0;
                for ( m=0 ; m < K ; m++ ){
                    /*temp_cplx.re += U_cplx[i+m*M].re * V_cplx[j+m*N].re
                        - U_cplx[i+m*M].im * V_cplx[j+m*N].im;
                    temp_cplx.im += U_cplx[i+m*M].im * V_cplx[j+m*N].re
                        + U_cplx[i+m*M].re * V_cplx[j+m*N].im; */
                    temp_cplx.re += U_cplx[K*i+m].re * V_cplx[K*j+m].re
                        - U_cplx[K*i+m].im * V_cplx[K*j+m].im;
                    temp_cplx.im += U_cplx[K*i+m].im * V_cplx[K*j+m].re
                        + U_cplx[K*i+m].re * V_cplx[K*j+m].im;
                }
                output[k] = temp_cplx.re;
                output_imag[k] = temp_cplx.im;
                
              }
            } else if (COMPLEX) {
              /* TRANSPOSE VERSION: UPDATED */
              for ( k=0 ; k < nOmega ; k++ ){
                i = (mwIndex) ( (mwIndex)(omega[k]-1) % M);
                j = (mwIndex) ( (mwIndex)(omega[k]-1)/ M);
                /*temp_cplx = my_zdot( (int*) &K, U_cplx+i, (int*)&M, V_cplx+j, (int*)&N ); */
                temp_cplx = my_zdot( (int*) &K, U_cplx+i*K, (int*)&one, V_cplx+j*K, (int*)&one ); 
                output[k] = temp_cplx.re;
                output_imag[k] = temp_cplx.im;
              }

            } else {
              /* TRANSPOSE VERSION: UPDATED */
              for ( k=0 ; k < nOmega ; k++ ){
                /* don't forget that Matlab is 1-indexed, C is 0-indexed */
                i = (mwIndex) ( (mwIndex)(omega[k]-1) % M);
                j = (mwIndex) ( (mwIndex)(omega[k]-1)/ M);
                /*output[k] = my_ddot( (int*)&K, U+i, (int*)&M, V+j, (int*)&N );*/
                output[k] = my_ddot( (int*)&K, U+i*K, (int*)&one, V+j*K, (int*)&one );
              }
            }
        } else {  /* (USE_BLAS) is true */
            /* We already have the full matrix, so just find the entries */
            if (COMPLEX) {
                for ( k=0 ; k < nOmega ; k++ ){
                    output[k] = output_cplx[ (mwIndex)omega[k] -1 ].re;
                    output_imag[k] = output_cplx[ (mwIndex)omega[k] - 1 ].im;
                }
                mxFree( output_cplx );
            } else {
                for ( k=0 ; k < nOmega ; k++ ){
                    /*
                    i = (mwIndex) ( (mwIndex)(omega[k]-1) % M);
                    j = (mwIndex) ( (mwIndex)(omega[k]-1)/ M);
                    output[k] = outputBLAS( j*M + i );
                    */
                    /* This now simplifies a lot! */
                    output[k] = outputBLAS[ (mwIndex)omega[k] - 1 ];
                }
                mxFree( outputBLAS );
            }
        }

    } else {

        /* ----------- MODE 2 ------------------------------- */

        if (SPARSE) {
            /* sparse array indices in Matlab are rather confusing;
             * see the mxSetJc help file to get started.  The Ir index
             * is straightforward: it contains rows indices of nonzeros,
             * in column-major order.  But the Jc index is tricky... 
             * Basically, Jc (which has N+1 entries, not nnz entries like Ir)
             * tells you which Ir entries correspond to the jth row, thus fully 
             * specifying the indices.  Ir[ Jc[j]:Jc[J+1] ] are the rows
             * that correspond to column j. This works because Ir is
             * in column-major order.   For this to work (and match A(omega)),
             * we need omega to be sorted!  
             *Note: everything is already 0-based, not 1-based
             * */
            omegaI = mxGetIr( prhs[2] );
            omegaJ = mxGetJc( prhs[2] );
            
            if ( USE_BLAS ) {
                /* We already have the full matrix, so just find the entries */
                if (COMPLEX) {
                    for ( j=0 ; j < N ; j++ ){
                        for ( k = omegaJ[j] ; k < omegaJ[j+1] ; k++ ) {
                            i = omegaI[k];
                            output[k] = output_cplx[ j*M + i ].re;
                            output_imag[k] = output_cplx[ j*M + i ].im;
                        }
                    }
                    mxFree( output_cplx );
                } else {
                    for ( j=0 ; j < N ; j++ ){
                        for ( k = omegaJ[j] ; k < omegaJ[j+1] ; k++ ) {
                            i = omegaI[k];
                            output[k] = outputBLAS[ j*M + i ];
                        }
                    }
                    mxFree( outputBLAS );
                }

            } else if ((COMPLEX)&&(LARGE_BIT)) {
                /* TRANSPOSE VERSION: this needs to be tested!!! */
                for ( j=0 ; j < N ; j++ ){
                    for ( k = omegaJ[j] ; k < omegaJ[j+1] ; k++ ) {
                        i = omegaI[k];

                        temp_cplx.re = 0.0;
                        temp_cplx.im = 0.0;
                        for ( m=0 ; m < K ; m++ ){
                            /*temp_cplx.re += U_cplx[i+m*M].re * V_cplx[j+m*N].re
                                - U_cplx[i+m*M].im * V_cplx[j+m*N].im;
                            temp_cplx.im += U_cplx[i+m*M].im * V_cplx[j+m*N].re
                                + U_cplx[i+m*M].re * V_cplx[j+m*N].im;*/
                            temp_cplx.re += U_cplx[K*i+m].re * V_cplx[K*j+m].re
                                - U_cplx[K*i+m].im * V_cplx[K*j+m].im;
                            temp_cplx.im += U_cplx[K*i+m].im * V_cplx[K*j+m].re
                                + U_cplx[K*i+m].re * V_cplx[K*j+m].im;
                        }
                        output[k] = temp_cplx.re;
                        output_imag[k] = temp_cplx.im;
                    }
                }
            } else if (COMPLEX) {
                /* TRANSPOSE VERSION: UPDATED */
                for ( j=0 ; j < N ; j++ ){
                    for ( k = omegaJ[j] ; k < omegaJ[j+1] ; k++ ) {
                        i = omegaI[k];
                        /* temp_cplx = my_zdot((int*) &K, U_cplx+i, (int*)&M, V_cplx+j, (int*)&N ); */
                        temp_cplx = my_zdot((int*) &K, U_cplx+i*K, (int*)&one, V_cplx+j*K, (int*)&one );
                        output[k] = temp_cplx.re;
                        output_imag[k] = temp_cplx.im;
                    }
                }
            } else {
                /* simple case */
                /* TRANSPOSE VERSION: UPDATED */
                for ( j=0 ; j < N ; j++ ){
                    for ( k = omegaJ[j] ; k < omegaJ[j+1] ; k++ ) {
                        i = omegaI[k];
                        /*output[k] = my_ddot( (int*)&K, U+i, (int*)&M, V+j, (int*)&N );*/
                        output[k] = my_ddot( (int*)&K, U+i*K, (int*)&one, V+j*K, (int*)&one );
                    }
                }
            }
        /* ----------- MODE 3 ------------------------------- */
        } else {
            /* we have omegaX and omegaY, the row and column indices */
            nOmega1 = mxGetM( prhs[3] );
            nOmega2 = mxGetN( prhs[3] );
            if ( (nOmega1 != 1) && (nOmega2 != 1) ) {
                printUsage();
                mexErrMsgTxt("OmegaY must be a vector");
            }
            nOmega1 = nOmega1 < nOmega2 ? nOmega2 : nOmega1;
            if ( nOmega1 != nOmega ) {
                printUsage();
    mexErrMsgTxt("In subscript index format, subscript vectors must be same length.");
            }
            omegaX = mxGetPr(prhs[2]);
            omegaY = mxGetPr(prhs[3]);

            if ( USE_BLAS ) {
                /* We already have the full matrix, so just find the entries */
                if (COMPLEX) {
                    for ( k=0 ; k < nOmega ; k++ ){
                        i = omegaX[k] - 1;
                        j = omegaY[k] - 1;
                        output[k] = output_cplx[ j*M + i ].re;
                        output_imag[k] = output_cplx[ j*M + i ].im;
                    }
                    mxFree( output_cplx );
                } else {
                    for ( k=0 ; k < nOmega ; k++ ){
                        i = omegaX[k] - 1;
                        j = omegaY[k] - 1;
                        output[k] = outputBLAS[ j*M + i ];
                    }
                    mxFree( outputBLAS );
                }

            } else if ((COMPLEX)&&(LARGE_BIT)) { 
                /* TRANSPOSE VERSION: this needs to be tested!!! */
                for ( k=0 ; k < nOmega ; k++ ){
                    i = omegaX[k] - 1;
                    j = omegaY[k] - 1;
                    temp_cplx.re = 0.0;
                    temp_cplx.im = 0.0;
                    for ( m=0 ; m < K ; m++ ){
                        /*temp_cplx.re += U_cplx[i+m*M].re * V_cplx[j+m*N].re
                            - U_cplx[i+m*M].im * V_cplx[j+m*N].im;
                        temp_cplx.im += U_cplx[i+m*M].im * V_cplx[j+m*N].re
                            + U_cplx[i+m*M].re * V_cplx[j+m*N].im; */
                        temp_cplx.re += U_cplx[K*i+m].re * V_cplx[K*j+m].re
                            - U_cplx[K*i+m].im * V_cplx[K*j+m].im;
                        temp_cplx.im += U_cplx[K*i+m].im * V_cplx[K*j+m].re
                            + U_cplx[K*i+m].re * V_cplx[K*j+m].im;
                    }
                    output[k] = temp_cplx.re;
                    output_imag[k] = temp_cplx.im;
                }
            } else if (COMPLEX) {
                /* TRANSPOSE VERSION: UPDATED */
                for ( k=0 ; k < nOmega ; k++ ){
                    i = omegaX[k] - 1;
                    j = omegaY[k] - 1;
                    /* temp_cplx = my_zdot( (int*)&K, U_cplx+i, (int*)&M, V_cplx+j, (int*)&N ); */
                    temp_cplx = my_zdot( (int*)&K, U_cplx+i*K, (int*)&one, V_cplx+j*K, (int*)&one );
                    output[k] = temp_cplx.re;
                    output_imag[k] = temp_cplx.im;
                }
            } else {
                /* TRANSPOSE VERSION: UPDATED */
                for ( k=0 ; k < nOmega ; k++ ){
                    i = omegaX[k] - 1;
                    j = omegaY[k] - 1;
                    /* output[k] = my_ddot( (int*)&K, U+i, (int*)&M, V+j, (int*)&N ); */
                    output[k] = my_ddot( (int*)&K, U+i*K, (int*)&one, V+j*K, (int*)&one );
                }
            }

        }
    }

}