// gridA[sum(ngrid)] ............ grids to compute predictive quantities for each observation // loggridA[sum(ngrid)] ......... logarithm of the grid // ngrid[nobs] .................. lengths of grids for each observation // onlyAver ..................... 0/1: compute only predictive quantities or return values as well? // predictP[4] .................. 0/1 indicating which predictive quantities are to be computed // predictP[0] ... densities? // predictP[1] ... survivor functions? // predictP[2] ... hazards? // predictP[3] ... cumulative hazards? // M ............................ McMC sample size (total, 'skip' and 'by' iterations included) // * M should be <= number of rows in *.sim files // * here: it is an index of the last iteration used to compute the average // skip ......................... how many rows are to be skipped at the beginning of the sample // by ........................... only every 'by' G-spline will be taken into account // nwrite ....................... frequency of informing the user about the progress // version ...................... arbitrary or 32 // if = 32, then model for doubly-interval censored data is assumed with G-spline errors // and bivariate normal random intercepts in the onset and time-to-event parts of the model // Onset ........................ only used by version = 32 // equal to 1 if we are predicting the onset // equak to 0 if we are predicting the event // errP ......................... error flag (0 on output if everything OK) // void predictive_GS(double *averDens, double *averS, double *averHaz, double *averCumHaz, double *valDens, double *valS, double *valHaz, double *valCumHaz, double *quantDens, double *quantS, double *quantHaz, double *quantCumHaz, const int *dimsP, const double *X, const int *obsdims, int *M_now, char **dirP, char **extensP, char **extens_adjP, const int *GsplI, const int *objBetaI, const double *objBetaD, const int *objbI, const double *objbD, const int *b_GsplI, const double *gridA, const double *loggridA, const int *ngrid, double *probsA, const int *nquant, int *onlyAver, const int *predictP, const int *M, const int *skip, const int *by, const int *nwrite, const int *version, const int *Onset, int *errP) { try{ GetRNGstate(); double dtemp; int itemp; int i, j, ix; double tmpd; *errP = 0; string dir = *dirP; string extens = *extensP; string extens_adj = *extens_adjP; /*** Dimensionality parameters ***/ const int *nobs = dimsP; const int *ncluster = dimsP + 1; const int *nwithin = dimsP + 2; const int M_now_max = *M_now; /*** What to predict? ***/ const int *predDens = predictP + 0; const int *predS = predictP + 1; const int *predHaz = predictP + 2; const int *predCumHaz = predictP + 3; /*** Quantiles ***/ if (*nquant <= 0) *onlyAver = 1; /*** Needed G-spline parameters ***/ const int *dim = GsplI + 0; const int *total_length = GsplI + 1; const int *GsplK = GsplI + 2; /* K1 (and K2) */ int *Glength = (int*) calloc(*dim, sizeof(int)); if (!Glength) throw returnR("Not enough memory available in predictive_GS (Glength)", 1); for (j = 0; j < *dim; j++) Glength[j] = 2*GsplK[j] + 1; /*** Check obsdims ***/ for (i = 0; i < *nobs; i++){ if (obsdims[i] < 0 || obsdims[i] >= *dim) throw returnR("Error: Inconsistent 'obsdims' parameter supplied to predictive_GS", 1); } /*** Check grid and log-grid ***/ int sum_ngrid = 0; for (i = 0; i < *nobs; i++) sum_ngrid += ngrid[i]; /*** Object for regression parameters ***/ BetaGamma* beta = new BetaGamma; if (!beta) throw returnR("Not enough memory available in predictive_GS (beta)", 1); *beta = BetaGamma(objBetaI, objBetaD); /*** Object for random effects ***/ RandomEff *bb = new RandomEff; RandomEff32::RE *db = new RandomEff32::RE; bool reff_NORMAL = true; /** BUT NOT version = 32 !**/ /*** Objects for bivariate normal random effects in version = 32 ***/ double *dval, *bval, *dbval; double D32[7] = {1, 0, 1, 2, 1, 0, 1}; /** parD argument for RandomEff32::RE initializer (filled arbitrary) **/ if (*version == 32){ reff_NORMAL = false; dval = (double*) calloc(objbI[2], sizeof(double)); // objbI[2] = nCluster bval = (double*) calloc(objbI[2], sizeof(double)); // objbI[2] = nCluster RandomEff32::init(db, dval, bval, D32, objbI, objbI); if (*Onset) dbval = dval; else dbval = bval; } else{ dval = NULL; bval = NULL; dbval = NULL; if (beta->nRandom()){ *bb = RandomEff(objbI, objbD); if (bb->type_prior() == Gspline_) reff_NORMAL = false; } } /*** Object for covariance matrix of random effects ***/ /*** or arrays for G-spline parameters definig distribution of random effects ***/ CovMatrix *DD = new CovMatrix; const int nD = (beta->nRandom() * (beta->nRandom() + 1)) / 2; const int *dim_b = b_GsplI + 0; const int *total_length_b = b_GsplI + 1; int k_effect_b; int *rM_b = &itemp; double *cum_w_b = &dtemp; double *sig_scale_b = &dtemp; double *prop_mu_b = &dtemp; if (*version != 32){ if (beta->nRandom()){ if (reff_NORMAL){ int DDparmI[2]; DDparmI[0] = beta->nRandom(); DDparmI[1] = InvWishart; /** it does not matter what is filled here **/ double *DDparmD = (double*) calloc(2*nD + 1, sizeof(double)); if (!DDparmD) throw returnR("Not enough memory available in predictive_GS (DDparmD)", 1); for (j = 0; j < beta->nRandom(); j++){ /** initial cov matrix and scale matrix equal to identity **/ ix = (j * (2*beta->nRandom() - j + 1))/2; /** again, it does not matter what is filled here **/ DDparmD[ix] = DDparmD[nD + 1 + ix] = 1.0; /** initial matrix must only be positive definite **/ for (i = j+1; i < beta->nRandom(); i++){ /** to pass the CovMatrix constructor **/ DDparmD[ix + i - j] = DDparmD[nD + 1 + ix + i - j] = 0.0; } } DDparmD[nD] = beta->nRandom() + 2; /** 'prior degrees of freedom', it does not matter what **/ *DD = CovMatrix(DDparmI, DDparmD); free(DDparmD); } else{ /** G-spline random effects **/ cum_w_b = (double*) calloc(*total_length_b, sizeof(double)); prop_mu_b = (double*) calloc(*total_length_b, sizeof(double)); sig_scale_b = (double*) calloc(*dim_b, sizeof(double)); rM_b = (int*) calloc(*ncluster, sizeof(int)); if (!cum_w_b || !prop_mu_b || !sig_scale_b) throw returnR("Not enough memory available in predictive_GS (cum_w_b/sig_scale_b)", 1); if (!rM_b) throw returnR("Not enough memory available in predictive_GS (rM_b)", 1); } } } /** end of if (*version != 32) **/ /*** Space for linear predictors ***/ double *linPred = (double*) calloc(*nobs, sizeof(double)); if (!linPred) throw returnR("Not enough memory available in predictive_GS (linPred)", 1); for (i = 0; i < *nobs; i++) linPred[i] = 0.0; /*** Allocate memory for needed quantities from simulated G-splines ***/ int k_effect; double *sigma = (double*) calloc(*dim, sizeof(double)); double *gamma = (double*) calloc(*dim, sizeof(double)); double *delta = (double*) calloc(*dim, sizeof(double)); double *intcpt = (double*) calloc(*dim, sizeof(double)); double *scale = (double*) calloc(*dim, sizeof(double)); double *delta_sig = (double*) calloc(*dim, sizeof(double)); double *inv_sig_scale = (double*) calloc(*dim, sizeof(double)); if (!sigma || !gamma || !delta || !inv_sig_scale || !intcpt || !scale || !delta_sig) throw returnR("Not enough memory available in predictive_GS (sigma/gamma/delta/intcpt/scale/delta_sig/inv_sig_scale)", 1); double **w_marg = (double**) calloc(*dim, sizeof(double*)); double **mu_sig_marg = (double**) calloc(*dim, sizeof(double*)); if (!w_marg || !mu_sig_marg) throw returnR("Not enough memory available in predictive_GS (w_marg/sc_mu_marg)", 1); for (j = 0; j < *dim; j++){ w_marg[j] = (double*) calloc(Glength[j], sizeof(double)); mu_sig_marg[j] = (double*) calloc(Glength[j], sizeof(double)); if (!w_marg[j] || !mu_sig_marg[j]) throw returnR("Not enough memory available in predictive_GS (w_marg[j]/mu_sig_marg[j])", 1); } /*** Open files with simulated G-splines ***/ std::string kpath = dir + "/mixmoment" + extens + ".sim"; std::string wpath = dir + "/mweight" + extens + ".sim"; std::string mupath = dir + "/mmean" + extens + ".sim"; std::string sigmapath = dir + "/gspline" + extens + ".sim"; std::ifstream kfile, wfile, mufile, sigmafile; openGsplineFiles(kfile, wfile, mufile, sigmafile, kpath, wpath, mupath, sigmapath, *skip + 1); /* skip also header */ /*** Open files with simulated remaining quantities ***/ std::string betapath = dir + "/beta" + extens + ".sim"; std::ifstream betafile; std::string Dpath = dir + "/D" + extens + ".sim"; std::ifstream Dfile; std::string D32path = dir + "/D" + ".sim"; std::ifstream D32file; std::string kpath_b = dir + "/mixmoment" + extens_adj + ".sim"; std::string wpath_b = dir + "/mweight" + extens_adj + ".sim"; std::string mupath_b = dir + "/mmean" + extens_adj + ".sim"; std::string sigmapath_b = dir + "/gspline" + extens_adj + ".sim"; std::ifstream kfile_b, wfile_b, mufile_b, sigmafile_b; openRegresFiles(betafile, Dfile, betapath, Dpath, *skip + 1, beta->nbeta(), beta->nRandom(), reff_NORMAL); /* skip also header */ if (*version == 32){ openD32File(D32file, D32path, *skip + 1); /* skip also header */ } else{ if (beta->nRandom() && !reff_NORMAL){ openGsplineFiles(kfile_b, wfile_b, mufile_b, sigmafile_b, kpath_b, wpath_b, mupath_b, sigmapath_b, *skip + 1); } } /*** Reset averages ***/ resetAverage(averDens, nobs, ngrid, predDens); resetAverage(averS, nobs, ngrid, predS); resetAverage(averHaz, nobs, ngrid, predHaz); resetAverage(averCumHaz, nobs, ngrid, predCumHaz); /*** Loop over McMC iterations ***/ double *vvDens = valDens; double *vvS = valS; double *vvHaz = valHaz; double *vvCumHaz = valCumHaz; const int *shift_pointer_inEval = (*onlyAver ? &ONE_INT : &M_now_max); if (*skip >= *M) throw returnR("More McMC iterations should be skipped than available", 1); readGsplineFromFiles2(&k_effect, w_marg, mu_sig_marg, gamma, sigma, delta, intcpt, scale, delta_sig, 0, *skip, *dim, *total_length, GsplK, kfile, wfile, mufile, sigmafile, kpath, wpath, mupath, sigmapath); readRegresFromFiles(beta, DD, 0, *skip, betafile, Dfile, betapath, Dpath, reff_NORMAL); if (*version == 32){ readDfromFile(db, 0, *skip, D32file, D32path); predict_db(db); linPred_GS(linPred, beta, dbval, X, nwithin, nobs, ncluster); } else{ if (beta->nRandom()){ if (reff_NORMAL){ bb->predictNormalRE(beta, DD); } else{ readGsplineFromFiles3(&k_effect_b, cum_w_b, prop_mu_b, sig_scale_b, 0, *skip, *dim_b, *total_length_b, kfile_b, wfile_b, mufile_b, sigmafile_b, kpath_b, wpath_b, mupath_b, sigmapath_b); bb->predictGspl_intcpt(&k_effect_b, cum_w_b, prop_mu_b, sig_scale_b, rM_b); } } linPred_GS(linPred, beta, bb->bMP(), X, nwithin, nobs, ncluster); } evalPredFuns(averDens, averS, averHaz, averCumHaz, vvDens, vvS, vvHaz, vvCumHaz, obsdims, nobs, ngrid, gridA, loggridA, linPred, dim, Glength, w_marg, mu_sig_marg, intcpt, sigma, scale, inv_sig_scale, predictP, &_zero_weight, shift_pointer_inEval); *M_now = 1; int by_1 = *by - 1; int jump_value = (*onlyAver ? 0 : 1); int backs = 0; Rprintf("Iteration "); for (int iter = *skip + 1 + (*by); iter <= *M; iter += (*by)){ if (*M_now >= M_now_max) throw returnR("Error: Higher sample size would be used than indicated", 1); if (*predDens) vvDens += jump_value; if (*predS) vvS += jump_value; if (*predHaz) vvHaz += jump_value; if (*predCumHaz) vvCumHaz += jump_value; readGsplineFromFiles2(&k_effect, w_marg, mu_sig_marg, gamma, sigma, delta, intcpt, scale, delta_sig, by_1, iter, *dim, *total_length, GsplK, kfile, wfile, mufile, sigmafile, kpath, wpath, mupath, sigmapath); readRegresFromFiles(beta, DD, by_1, iter, betafile, Dfile, betapath, Dpath, reff_NORMAL); if (*version == 32){ readDfromFile(db, by_1, iter, D32file, D32path); predict_db(db); linPred_GS(linPred, beta, dbval, X, nwithin, nobs, ncluster); } else{ if (beta->nRandom()){ if (reff_NORMAL){ bb->predictNormalRE(beta, DD); } else{ readGsplineFromFiles3(&k_effect_b, cum_w_b, prop_mu_b, sig_scale_b, by_1, iter, *dim_b, *total_length_b, kfile_b, wfile_b, mufile_b, sigmafile_b, kpath_b, wpath_b, mupath_b, sigmapath_b); bb->predictGspl_intcpt(&k_effect_b, cum_w_b, prop_mu_b, sig_scale_b, rM_b); } } linPred_GS(linPred, beta, bb->bMP(), X, nwithin, nobs, ncluster); } evalPredFuns(averDens, averS, averHaz, averCumHaz, vvDens, vvS, vvHaz, vvCumHaz, obsdims, nobs, ngrid, gridA, loggridA, linPred, dim, Glength, w_marg, mu_sig_marg, intcpt, sigma, scale, inv_sig_scale, predictP, &_zero_weight, shift_pointer_inEval); (*M_now)++; if (!(iter % (*nwrite)) || iter == *M){ for (i = 0; i < backs; i++) Rprintf("\b"); Rprintf("%d", iter); backs = int(log10(double(iter))) + 1; } } /** end of the while over iterations **/ Rprintf("\n"); /*** Close files with simulated G-splines and regression quantities ***/ closeGsplineFiles(kfile, wfile, mufile, sigmafile); closeRegresFiles(betafile, Dfile, beta->nbeta(), beta->nRandom(), reff_NORMAL); if (*version == 32){ D32file.close(); } else{ if (beta->nRandom() && !reff_NORMAL) closeGsplineFiles(kfile_b, wfile_b, mufile_b, sigmafile_b); } /*** McMC averages ***/ cumsum2average(averDens, M_now, nobs, ngrid, predDens); cumsum2average(averS, M_now, nobs, ngrid, predS); cumsum2average(averHaz, M_now, nobs, ngrid, predHaz); cumsum2average(averCumHaz, M_now, nobs, ngrid, predCumHaz); /*** Indeces of quantile values in sampled chain (indexing starting from 0) ***/ // indquant1, indquant2 ..... quantile = q*sample[indquant1] + (1-q)sample[indquant2] // int *indquant1 = &itemp; int *indquant2 = &itemp; if (!(*onlyAver)){ indquant1 = (int*) calloc(*nquant, sizeof(int)); indquant2 = (int*) calloc(*nquant, sizeof(int)); if (!indquant1 || !indquant2) throw returnR("Error Not enough memory available in predictive_GS (indquant1/indquant2)", 1); for (i = 0; i < *nquant; i++){ if (probsA[i] < 0 || probsA[i] > 1) throw returnR("Error: Incorrect probs values supplied.", 1); if (probsA[i] <= 0) indquant1[i] = indquant2[i] = 0; else{ if (probsA[i] >= 1) indquant1[i] = indquant2[i] = *M_now - 1; else{ tmpd = probsA[i] * double(*M_now); if (fabs(tmpd - floor(tmpd + 1e-8)) < 1e-8){ indquant1[i] = int(floor(tmpd)) - 1; indquant2[i] = int(floor(tmpd)); } else{ indquant1[i] = indquant2[i] = int(floor(tmpd)); } } } } Rprintf("\nComputing quantiles."); value2quantile(valDens, quantDens, probsA, indquant1, indquant2, nquant, M_now, nobs, ngrid, predDens, shift_pointer_inEval); value2quantile(valS, quantS, probsA, indquant1, indquant2, nquant, M_now, nobs, ngrid, predS, shift_pointer_inEval); value2quantile(valHaz, quantHaz, probsA, indquant1, indquant2, nquant, M_now, nobs, ngrid, predHaz, shift_pointer_inEval); value2quantile(valCumHaz, quantCumHaz, probsA, indquant1, indquant2, nquant, M_now, nobs, ngrid, predCumHaz, shift_pointer_inEval); } PutRNGstate(); /*** Cleaning ***/ if (!(*onlyAver)){ free(indquant1); free(indquant2); } for (j = 0; j < *dim; j++){ free(w_marg[j]); free(mu_sig_marg[j]); } free(w_marg); free(mu_sig_marg); free(sigma); free(gamma); free(delta); free(inv_sig_scale); free(intcpt); free(scale); free(delta_sig); free(Glength); free(linPred); delete DD; if (*version == 32){ free(bval); free(dval); } else{ if (beta->nRandom()){ if (reff_NORMAL){ // delete DD; } else{ free(sig_scale_b); free(prop_mu_b); free(cum_w_b); free(rM_b); } } } delete db; delete bb; delete beta; return; } catch(returnR rr){ *errP = rr.errflag(); PutRNGstate(); return; } }
/****************************************************************************** ** entry point for the mex call ** nlhs - number of outputs ** plhs - pointer to array of outputs ** nrhs - number of inputs ** prhs - pointer to array of inputs ******************************************************************************/ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { /************************************************************* ** this function takes 4-6 arguments: ** flag = which algorithm to use, ** k = number of features to select, ** featureMatrix[][] = matrix of features, ** classColumn[] = targets, ** optionalParam1 = (path angle or beta value), ** optionalParam2 = (gamma value), ** the arguments should all be discrete integers. ** and has one output: ** selectedFeatures[] of size k *************************************************************/ int flag, k; double optionalParam1, optionalParam2; int numberOfFeatures, numberOfSamples, numberOfTargets; double *featureMatrix, *targets, *output, *outputFeatures; double entropyTest; int i,j; /************************************************************ ** number to function map ** 1 = MIFS ** 2 = mRMR ** 3 = CMIM ** 4 = JMI ** 5 = DISR ** 6 = CIFE ** 7 = ICAP ** 8 = CondRed ** 9 = BetaGamma ** 10 = CMI *************************************************************/ if (nlhs > 1) { printf("Incorrect number of output arguments"); }/*if not 1 output*/ if ((nrhs < 4) || (nrhs > 6)) { printf("Incorrect number of input arguments"); return; }/*if not 4-6 inputs*/ /*get the flag for which algorithm*/ flag = (int) mxGetScalar(prhs[0]); /*get the number of features to select, cast out as it is a double*/ k = (int) mxGetScalar(prhs[1]); numberOfFeatures = mxGetN(prhs[2]); numberOfSamples = mxGetM(prhs[2]); numberOfTargets = mxGetM(prhs[3]); if (nrhs == 6) { optionalParam1 = (double) mxGetScalar(prhs[4]); optionalParam2 = (double) mxGetScalar(prhs[5]); } else if (nrhs == 5) { optionalParam1 = (double) mxGetScalar(prhs[4]); optionalParam2 = 0.0; } if (numberOfTargets != numberOfSamples) { printf("Number of targets must match number of samples\n"); printf("Number of targets = %d, Number of Samples = %d, Number of Features = %d\n",numberOfTargets,numberOfSamples,numberOfFeatures); plhs[0] = mxCreateDoubleMatrix(0,0,mxREAL); return; }/*if size mismatch*/ else if ((k < 1) || (k > numberOfFeatures)) { printf("You have requested k = %d features, which is not possible\n",k); plhs[0] = mxCreateDoubleMatrix(0,0,mxREAL); return; } else { featureMatrix = mxGetPr(prhs[2]); targets = mxGetPr(prhs[3]); /*double calculateEntropy(double *dataVector, int vectorLength)*/ entropyTest = calculateEntropy(targets,numberOfSamples); if (entropyTest < 0.0000001) { printf("The class label Y has entropy of 0, therefore all mutual informations containing Y will be 0. No feature selection is performed\n"); plhs[0] = mxCreateDoubleMatrix(0,0,mxREAL); return; } else { /*printf("Flag = %d, k = %d, numFeatures = %d, numSamples = %d\n",flag,k,numberOfFeatures,numberOfSamples);*/ switch (flag) { case 1: /* MIFS */ { plhs[0] = mxCreateDoubleMatrix(k,1,mxREAL); output = (double *)mxGetPr(plhs[0]); if (nrhs == 4) { /* MIFS is Beta = 1, Gamma = 0 */ optionalParam1 = 1.0; optionalParam2 = 0.0; } /*void BetaGamma(int k, long noOfSamples, long noOfFeatures,double *featureMatrix, double *classColumn, double *outputFeatures, double beta, double gamma)*/ BetaGamma(k,numberOfSamples,numberOfFeatures,featureMatrix,targets,output,optionalParam1,optionalParam2); incrementVector(output,k); break; } case 2: /* mRMR */ { plhs[0] = mxCreateDoubleMatrix(k,1,mxREAL); output = (double *)mxGetPr(plhs[0]); /*void mRMR_D(int k, int noOfSamples, int noOfFeatures,double *featureMatrix, double *classColumn, double *outputFeatures)*/ mRMR_D(k,numberOfSamples,numberOfFeatures,featureMatrix,targets,output); incrementVector(output,k); break; } case 3: /* CMIM */ { plhs[0] = mxCreateDoubleMatrix(k,1,mxREAL); output = (double *)mxGetPr(plhs[0]); /*void CMIM(int k, int noOfSamples, int noOfFeatures,double *featureMatrix, double *classColumn, double *outputFeatures)*/ CMIM(k,numberOfSamples,numberOfFeatures,featureMatrix,targets,output); incrementVector(output,k); break; } case 4: /* JMI */ { plhs[0] = mxCreateDoubleMatrix(k,1,mxREAL); output = (double *)mxGetPr(plhs[0]); /*void JMI(int k, int noOfSamples, int noOfFeatures,double *featureMatrix, double *classColumn, double *outputFeatures)*/ JMI(k,numberOfSamples,numberOfFeatures,featureMatrix,targets,output); incrementVector(output,k); break; } case 5: /* DISR */ { plhs[0] = mxCreateDoubleMatrix(k,1,mxREAL); output = (double *)mxGetPr(plhs[0]); /*void DISR(int k, int noOfSamples, int noOfFeatures,double *featureMatrix, double *classColumn, double *outputFeatures)*/ DISR(k,numberOfSamples,numberOfFeatures,featureMatrix,targets,output); incrementVector(output,k); break; } case 6: /* CIFE */ { plhs[0] = mxCreateDoubleMatrix(k,1,mxREAL); output = (double *)mxGetPr(plhs[0]); /* CIFE is Beta = 1, Gamma = 1 */ optionalParam1 = 1.0; optionalParam2 = 1.0; /*void BetaGamma(int k, long noOfSamples, long noOfFeatures,double *featureMatrix, double *classColumn, double *outputFeatures, double beta, double gamma)*/ BetaGamma(k,numberOfSamples,numberOfFeatures,featureMatrix,targets,output,optionalParam1,optionalParam2); incrementVector(output,k); break; } case 7: /* ICAP */ { plhs[0] = mxCreateDoubleMatrix(k,1,mxREAL); output = (double *)mxGetPr(plhs[0]); /*void ICAP(k,numberOfSamples,numberOfFeatures,featureMatrix,targets,output);*/ ICAP(k,numberOfSamples,numberOfFeatures,featureMatrix,targets,output); incrementVector(output,k); break; } case 8: /* CondRed */ { plhs[0] = mxCreateDoubleMatrix(k,1,mxREAL); output = (double *)mxGetPr(plhs[0]); /* CondRed is Beta = 0, Gamma = 1 */ optionalParam1 = 0.0; optionalParam2 = 1.0; /*void BetaGamma(int k, long noOfSamples, long noOfFeatures,double *featureMatrix, double *classColumn, double *outputFeatures, double beta, double gamma)*/ BetaGamma(k,numberOfSamples,numberOfFeatures,featureMatrix,targets,output,optionalParam1,optionalParam2); incrementVector(output,k); break; } case 9: /* BetaGamma */ { if (nrhs != 6) { printf("Insufficient arguments specified for Beta Gamma FS\n"); plhs[0] = mxCreateDoubleMatrix(0,0,mxREAL); return; } else { plhs[0] = mxCreateDoubleMatrix(k,1,mxREAL); output = (double *)mxGetPr(plhs[0]); /*void BetaGamma(int k, long noOfSamples, long noOfFeatures,double *featureMatrix, double *classColumn, double *outputFeatures, double beta, double gamma)*/ BetaGamma(k,numberOfSamples,numberOfFeatures,featureMatrix,targets,output,optionalParam1,optionalParam2); incrementVector(output,k); } break; } case 10: /* CMI */ { output = (double *)mxCalloc(k,sizeof(double)); /*void CondMI(int k, int noOfSamples, int noOfFeatures,double *featureMatrix, double *classColumn, double *outputFeatures)*/ CondMI(k,numberOfSamples,numberOfFeatures,featureMatrix,targets,output); i = 0; while((output[i] != -1) && (i < k)) { i++; } plhs[0] = mxCreateDoubleMatrix(i,1,mxREAL); outputFeatures = (double *)mxGetPr(plhs[0]); for (j = 0; j < i; j++) { outputFeatures[j] = output[j] + 1; /*C indexes from 0 not 1*/ }/*for number of selected features*/ mxFree(output); output = NULL; break; } }/*switch on flag*/ return; } } }/*mex function entry*/