Exemplo n.º 1
0
/*****************************************************************************
  Look at each available value, pretend to split on it, calculate the entropy 
  of what that would look like, pick the best reduction in entropy, and
  return that value to split on, reducing the available values by one.
 
  @param {char, int, ValueP, MushroomP} letter, attribute, valueList, shroomList
  @return {ValueP} highestGainValue the popped value that we want to split on.
******************************************************************************/
ValueP findHighestGain( char letter, int attribute, ValueP valueList, MushroomP shroomList ){
  ValueP valueIterate;
  valueIterate = valueList;
  ValueP highestGainValue;
  highestGainValue = NULL;
  MushroomP shroomIterate;
  shroomIterate = NULL;
  float gain, maxGain, currentEntropy, leftEntropy, rightEntropy;
  int leftCount, leftEdible, rightCount, rightEdible, shroomCount;
  gain = -1.0;
  maxGain = -1.0;
 
  /* go through each available attribute, and calculate the gain of each, but
   * only retain the highest value */
  while( valueIterate != NULL ){
    currentEntropy = 0.0;
    leftEntropy = 0.0;
    leftCount = 0;
    leftEdible = 0;
    rightEntropy = 0.0;
    rightCount = 0;
    rightEdible = 0;
    shroomIterate = shroomList;
    while( shroomIterate != NULL ){
      /* check to see if this mushroom would go to the right or to the left */
      if( shroomIterate->attributes[ valueIterate->attribute ] == valueIterate->letter ){
        /* it would go to the left, so now check and see if it's edible or not */
        leftCount++;
        if( shroomIterate->attributes[ attribute ] == letter ){
          leftEdible++;
        }
      } else {
        /* it would go to the right, so now check and see if it's edible or not */
        rightCount++;
        if( shroomIterate->attributes[ attribute ] == letter ){
          rightEdible++;
        }
      }
      shroomIterate = shroomIterate->next;
    }
    /* we now have the count values for everything that we need to perform our
     * gain calculation */
    shroomCount = leftCount + rightCount;
    currentEntropy = calculateEntropy( leftEdible + rightEdible, shroomCount );
    leftEntropy = calculateEntropy( leftEdible, leftCount );
    rightEntropy = calculateEntropy( rightEdible, rightCount ); 
      
    gain = currentEntropy - (float)( leftCount / shroomCount ) * leftEntropy - (float)( rightCount / shroomCount ) * rightEntropy;
    if( gain > maxGain ){
      maxGain = gain;
      highestGainValue = valueIterate;
    }
    valueIterate = valueIterate->next;
  }
 
  /* pop out the highestGainValue and return it */
  valueIterate = valueList;
  while( valueIterate != NULL ){
    if( valueIterate->next == highestGainValue ){
      valueIterate->next = highestGainValue->next;
      break;
    }
    valueIterate = valueIterate->next;
  }
  return( highestGainValue );
}
Exemplo n.º 2
0
/*******************************************************************************
**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 a flag and a variable number of arguments
  ** depending on the value of the flag and returns either a construct 
  ** containing probability estimates, a merged vector or a double value 
  ** representing an entropy or mutual information
  *****************************************************************************/
  
  int flag, i, numberOfSamples, checkSamples, thirdCheckSamples, numberOfFeatures, checkFeatures, thirdCheckFeatures;
  int  numArities, errorTest;
  double *dataVector, *condVector, *targetVector, *firstVector, *secondVector, *output, *numStates;
  double *matrix, *mergedVector, *arities;
  int *outputIntVector, *intArities;
  
  double *jointOutput, *numJointStates, *firstOutput, *numFirstStates, *secondOutput, *numSecondStates;
  
  ProbabilityState state;
  JointProbabilityState jointState;
  
  /*if (nlhs != 1)
  {
    printf("Incorrect number of output arguments\n");
  }//if not 1 output
  */
  switch (nrhs)
  {
    case 2:
    {
        /*printf("Must be H(X), calculateProbability(X), merge(X), normaliseArray(X)\n");*/
        break;
    }
    case 3:
    {
        /*printf("Must be H(XY), H(X|Y), calculateJointProbability(XY), I(X;Y)\n");*/
        break;
    }
    case 4:
    {
        /*printf("Must be I(X;Y|Z)\n");*/
        break;
    }
    default:
    {
        printf("Incorrect number of arguments, format is MIToolbox(\"FLAG\",varargin)\n");
        break;
    }
  }
  
  /* number to function map
  ** 1 = calculateProbability
  ** 2 = calculateJointProbability
  ** 3 = mergeArrays
  ** 4 = H(X)
  ** 5 = H(XY)
  ** 6 = H(X|Y)
  ** 7 = I(X;Y)
  ** 8 = I(X;Y|Z)
  ** 9 = normaliseArray
  */
  
  flag = *mxGetPr(prhs[0]);
  
  switch (flag)
  {
    case 1:
    {
      /*
      **calculateProbability
      */
      numberOfSamples = mxGetM(prhs[1]);
      dataVector = (double *) mxGetPr(prhs[1]);

      /*ProbabilityState calculateProbability(double *dataVector, int vectorLength);*/
      state = calculateProbability(dataVector,numberOfSamples);
      
      plhs[0] = mxCreateDoubleMatrix(state.numStates,1,mxREAL);
      plhs[1] = mxCreateDoubleMatrix(1,1,mxREAL);
      output = (double *)mxGetPr(plhs[0]);
      numStates = (double *) mxGetPr(plhs[1]);
      
      *numStates = state.numStates;
      
      for (i = 0; i < state.numStates; i++)
      {
        output[i] = state.probabilityVector[i];
      }
      
      break;
    }/*case 1 - calculateProbability*/
    case 2:
    {
      /*
      **calculateJointProbability
      */
      numberOfSamples = mxGetM(prhs[1]);
      firstVector = (double *) mxGetPr(prhs[1]);
      secondVector = (double *) mxGetPr(prhs[2]);

      /*JointProbabilityState calculateJointProbability(double *firstVector, double *secondVector int vectorLength);*/
      jointState = calculateJointProbability(firstVector,secondVector,numberOfSamples);
      
      plhs[0] = mxCreateDoubleMatrix(jointState.numJointStates,1,mxREAL);
      plhs[1] = mxCreateDoubleMatrix(1,1,mxREAL);
      plhs[2] = mxCreateDoubleMatrix(jointState.numFirstStates,1,mxREAL);
      plhs[3] = mxCreateDoubleMatrix(1,1,mxREAL);
      plhs[4] = mxCreateDoubleMatrix(jointState.numSecondStates,1,mxREAL);
      plhs[5] = mxCreateDoubleMatrix(1,1,mxREAL);
      jointOutput = (double *)mxGetPr(plhs[0]);
      numJointStates = (double *) mxGetPr(plhs[1]);
      firstOutput = (double *)mxGetPr(plhs[2]);
      numFirstStates = (double *) mxGetPr(plhs[3]);
      secondOutput = (double *)mxGetPr(plhs[4]);
      numSecondStates = (double *) mxGetPr(plhs[5]);
      
      *numJointStates = jointState.numJointStates;
      *numFirstStates = jointState.numFirstStates;
      *numSecondStates = jointState.numSecondStates;
      
      for (i = 0; i < jointState.numJointStates; i++)
      {
        jointOutput[i] = jointState.jointProbabilityVector[i];
      }
      for (i = 0; i < jointState.numFirstStates; i++)
      {
        firstOutput[i] = jointState.firstProbabilityVector[i];
      }
      for (i = 0; i < jointState.numSecondStates; i++)
      {
        secondOutput[i] = jointState.secondProbabilityVector[i];
      }
      
      break;
    }/*case 2 - calculateJointProbability */
    case 3:
    {
      /*
      **mergeArrays
      */
      numberOfSamples = mxGetM(prhs[1]);
      numberOfFeatures = mxGetN(prhs[1]);
            
      numArities = 0;
      if (nrhs > 2)
      {
        numArities = mxGetN(prhs[2]);
        /*printf("arities = %d, features = %d, samples = %d\n",numArities,numberOfFeatures,numberOfSamples);*/
      }
      
      plhs[0] = mxCreateDoubleMatrix(0,0,mxREAL);
      
      if (numArities == 0)
      {
        /*
        **no arities therefore compress output
        */
        if ((numberOfFeatures > 0) && (numberOfSamples > 0))
        { 
          matrix = (double *) mxGetPr(prhs[1]);
          mergedVector = (double *) mxCalloc(numberOfSamples,sizeof(double));
            
          plhs[0] = mxCreateDoubleMatrix(numberOfSamples,1,mxREAL);
          output = (double *)mxGetPr(plhs[0]);
          
          /*int mergeMultipleArrays(double *inputMatrix, double *outputVector, int matrixWidth, int vectorLength)*/
          mergeMultipleArrays(matrix, mergedVector, numberOfFeatures, numberOfSamples);
          for (i = 0; i < numberOfSamples; i++)
          {
            output[i] = mergedVector[i];
          }
          
          mxFree(mergedVector);
          mergedVector = NULL;
        }
      }
      else if (numArities == numberOfFeatures)
      {
        if ((numberOfFeatures > 0) && (numberOfSamples > 0))
        { 
          
          matrix = (double *) mxGetPr(prhs[1]);
          mergedVector = (double *) mxCalloc(numberOfSamples,sizeof(double));
          
          arities = (double *) mxGetPr(prhs[2]);
          intArities = (int *) mxCalloc(numberOfFeatures,sizeof(int));
          for (i = 0; i < numArities; i++)
          {
            intArities[i] = (int) floor(arities[i]);
          }
          
          /*int mergeMultipleArrays(double *inputMatrix, double *outputVector, int matrixWidth, int *arities, int vectorLength);*/
          errorTest = mergeMultipleArraysArities(matrix, mergedVector, numberOfFeatures, intArities, numberOfSamples);
           
          if (errorTest != -1)
          {
            plhs[0] = mxCreateDoubleMatrix(numberOfSamples,1,mxREAL);
            output = (double *)mxGetPr(plhs[0]);
            for (i = 0; i < numberOfSamples; i++)
            {
              output[i] = mergedVector[i];
            }
          }
          else
          {
            printf("Incorrect arities supplied. More states in data than specified\n");
          }
          
          mxFree(mergedVector);
          mergedVector = NULL;
        }
      }
      else
      {
        printf("Number of arities does not match number of features, arities should be a row vector\n");
      }
      
      break;
    }/*case 3 - mergeArrays*/
    case 4:
    {
      /*
      **H(X)
      */
      numberOfSamples = mxGetM(prhs[1]);
      numberOfFeatures = mxGetN(prhs[1]);
      
      dataVector = (double *) mxGetPr(prhs[1]);

      plhs[0] = mxCreateDoubleMatrix(1,1,mxREAL);
      output = (double *)mxGetPr(plhs[0]);

      if (numberOfFeatures == 1)
      {
        /*double calculateEntropy(double *dataVector, int vectorLength);*/
        *output = calculateEntropy(dataVector,numberOfSamples);
      }
      else
      {
        printf("No columns in input\n");
        *output = -1.0;
      }
      
      break;
    }/*case 4 - H(X)*/
    case 5:
    {
      /*
      **H(XY)
      */
      numberOfSamples = mxGetM(prhs[1]);
      checkSamples = mxGetM(prhs[2]);
      
      numberOfFeatures = mxGetN(prhs[1]);
      checkFeatures = mxGetN(prhs[2]);

      firstVector = mxGetPr(prhs[1]);
      secondVector = mxGetPr(prhs[2]);

      plhs[0] = mxCreateDoubleMatrix(1,1,mxREAL);
      output = (double *)mxGetPr(plhs[0]);


      if ((numberOfFeatures == 1) && (checkFeatures == 1))
      {
        if ((numberOfSamples == 0) && (checkSamples == 0))
        {
          *output = 0.0;
        }
        else if (numberOfSamples == 0)
        {
          *output = calculateEntropy(secondVector,numberOfSamples);
        }
        else if (checkSamples == 0)
        {
          *output = calculateEntropy(firstVector,numberOfSamples);
        }
        else if (numberOfSamples == checkSamples)
        {
          /*double calculateJointEntropy(double *firstVector, double *secondVector, int vectorLength);*/
          *output = calculateJointEntropy(firstVector,secondVector,numberOfSamples);
        }
        else
        {
          printf("Vector lengths do not match, they must be the same length\n");
          *output = -1.0;
        }
      }
      else
      {
        printf("No columns in input\n");
        *output = -1.0;
      }
      
      break;
    }/*case 5 - H(XY)*/
    case 6:
    {
      /*
      **H(X|Y)
      */
      numberOfSamples = mxGetM(prhs[1]);
      checkSamples = mxGetM(prhs[2]);
      
      numberOfFeatures = mxGetN(prhs[1]);
      checkFeatures = mxGetN(prhs[2]);

      dataVector = mxGetPr(prhs[1]);
      condVector = mxGetPr(prhs[2]);

      plhs[0] = mxCreateDoubleMatrix(1,1,mxREAL);
      output = (double *)mxGetPr(plhs[0]);

      if ((numberOfFeatures == 1) && (checkFeatures == 1))
      {
        if (numberOfSamples == 0)
        {
          *output = 0.0;
        }
        else if (checkSamples == 0)
        {
          *output = calculateEntropy(dataVector,numberOfSamples);
        }
        else if (numberOfSamples == checkSamples)
        {
          /*double calculateConditionalEntropy(double *dataVector, double *condVector, int vectorLength);*/
          *output = calculateConditionalEntropy(dataVector,condVector,numberOfSamples);
        }
        else
        {
          printf("Vector lengths do not match, they must be the same length\n");
          *output = -1.0;
        }
      }
      else
      {
        printf("No columns in input\n");
        *output = -1.0;
      }
      break;
    }/*case 6 - H(X|Y)*/
    case 7:
    {
      /*
      **I(X;Y)
      */
      numberOfSamples = mxGetM(prhs[1]);
      checkSamples = mxGetM(prhs[2]);

      numberOfFeatures = mxGetN(prhs[1]);
      checkFeatures = mxGetN(prhs[2]);
      
      firstVector = mxGetPr(prhs[1]);
      secondVector = mxGetPr(prhs[2]);

      plhs[0] = mxCreateDoubleMatrix(1,1,mxREAL);
      output = (double *)mxGetPr(plhs[0]);

      if ((numberOfFeatures == 1) && (checkFeatures == 1))
      {
        if ((numberOfSamples == 0) || (checkSamples == 0))
        {
          *output = 0.0;
        }
        else if (numberOfSamples == checkSamples)
        {
          /*double calculateMutualInformation(double *firstVector, double *secondVector, int vectorLength);*/
          *output = calculateMutualInformation(firstVector,secondVector,numberOfSamples);
        }
        else
        {
          printf("Vector lengths do not match, they must be the same length\n");
          *output = -1.0;
        }
      }
      else
      {
        printf("No columns in input\n");
        *output = -1.0;
      }
      break;
    }/*case 7 - I(X;Y)*/
    case 8:
    {
      /*
      **I(X;Y|Z)
      */
      numberOfSamples = mxGetM(prhs[1]);
      checkSamples = mxGetM(prhs[2]);
      thirdCheckSamples = mxGetM(prhs[3]);
      
      numberOfFeatures = mxGetN(prhs[1]);
      checkFeatures = mxGetN(prhs[2]);
      thirdCheckFeatures = mxGetN(prhs[3]);

      firstVector = mxGetPr(prhs[1]);
      targetVector = mxGetPr(prhs[2]);
      condVector = mxGetPr(prhs[3]);

      plhs[0] = mxCreateDoubleMatrix(1,1,mxREAL);
      output = (double *)mxGetPr(plhs[0]);
      
      if ((numberOfFeatures == 1) && (checkFeatures == 1))
      {
        if ((numberOfSamples == 0) || (checkSamples == 0))
        {
          *output = 0.0;
        }
        else if ((thirdCheckSamples == 0) || (thirdCheckFeatures != 1))
        {
          *output = calculateMutualInformation(firstVector,targetVector,numberOfSamples);
        }
        else if ((numberOfSamples == checkSamples) && (numberOfSamples == thirdCheckSamples))
        {
          /*double calculateConditionalMutualInformation(double *firstVector, double *targetVector, double *condVector, int vectorLength);*/
          *output = calculateConditionalMutualInformation(firstVector,targetVector,condVector,numberOfSamples);
        }
        else
        {
          printf("Vector lengths do not match, they must be the same length\n");
          *output = -1.0;
        }
      }
      else
      {
        printf("No columns in input\n");
        *output = -1.0;
      }
      break;
    }/*case 8 - I(X;Y|Z)*/
    case 9:
    {
      /*
      **normaliseArray
      */
      numberOfSamples = mxGetM(prhs[1]);
      dataVector = (double *) mxGetPr(prhs[1]);
      
      outputIntVector = (int *) mxCalloc(numberOfSamples,sizeof(int));

      plhs[0] = mxCreateDoubleMatrix(numberOfSamples,1,mxREAL);
      plhs[1] = mxCreateDoubleMatrix(1,1,mxREAL);
      output = (double *)mxGetPr(plhs[0]);
      numStates = (double *) mxGetPr(plhs[1]);
      
      /*int normaliseArray(double *inputVector, int *outputVector, int vectorLength);*/
      *numStates = normaliseArray(dataVector, outputIntVector, numberOfSamples);
      
      for (i = 0; i < numberOfSamples; i++)
      {
        output[i] = outputIntVector[i];
      }
      
      break;
    }/*case 9 - normaliseArray*/
    default:
    {
      printf("Unrecognised flag\n");
      break;
    }/*default*/
  }/*switch(flag)*/
  
  return;
}/*mexFunction()*/
/**
 * Check if connection is an anomaly
 */
void TfdAnomalyDetector::checkConnection(Connection* conn)
{
    uint32_t flowStartSec = 0;      // starttime of flow (seconds)
    uint64_t flowStartMillisec = 0; // starttime of flow (milliseconds)
    uint32_t host = 0;              // host in local network (srcIP or dstIP)
    string hostString;              // host displayed as string
    bool isSrc = false;
    float numFlowPackets;           // number of packets for current flow
    uint32_t srcIP;
    uint32_t dstIP;
    uint16_t srcPort;
    uint16_t dstPort;
    int odPair = 0;
    map<int, PortList>::iterator hostIt;
    
    // check if src or dst of current flow is local host
    if ((conn->srcIP & subnetmask) == subnet) {
        host = conn->srcIP;
        isSrc = true;
        
    } else if ((conn->dstIP & subnetmask) == subnet) {
        host = conn->dstIP;
        isSrc = false;
    } else {
        return;
    }
    
    // get number of packets for current flow
    numFlowPackets = ntohll(conn->srcPackets);
    
    // calc starttime for current flow
    flowStartMillisec = conn->srcTimeStart;
    flowStartSec = (flowStartMillisec + 500) / 1000; // srcTimeStart -rounded- to seconds
 
    // get appropriate timebin for array
    if (((flowStartSec - lastFlowStartSec) >= binSize) && lastFlowStartSec != 0) {  // todo: variable interval lengths (currently 1 sec) -> binSize
        timeBin++;      // next timebin
        if (timeBin >= TIMEBINS) {
        
          calculateEntropy();
          
          normalizeMatrix(srcIpEntropy, TIMEBINS);
          normalizeMatrix(dstIpEntropy, TIMEBINS);
          normalizeMatrix(srcPortEntropy, TIMEBINS);
          normalizeMatrix(dstPortEntropy, TIMEBINS);
                   
          calculateSingleWayMatrix();
          
          calculateExpectationMaximation();

          // restart calculation
          initTempArrays();   // init and delete IP/Port arrays
          timeBin = 0;        // set counter back
        }
        lastFlowStartSec = flowStartSec;
        lastFlowStartMilliSec = flowStartMillisec;
    }
         
    // get OD-value for array
    hostString = IPToString(host);
    int pos;
    for (int i = 0; i < 3; i++) {     // cut host into substrings, only use last part as index for array
      pos = hostString.find(".");
      hostString = hostString.substr(pos+1);
    }
    odPair = atoi(hostString.c_str()); // convert host-substring to int

    // save flowStart to calculate next timebin
    lastFlowStartSec = flowStartSec;
    
    
    // **** save number of packets to IP-Arrays
    if (isSrc) {
        srcIpPackets[timeBin][odPair] += numFlowPackets;
    } else {
        dstIpPackets[timeBin][odPair] += numFlowPackets;
    }
        
    // **** source port
    srcPort = ntohs(conn->srcPort);
    hostIt = srcPortMap.find(odPair);
    if(hostIt != srcPortMap.end()) {
        // host found in Map -> add port to vector
        PortListIterator portIt = find((hostIt->second).begin(), (hostIt->second).end(), srcPort);
        if (portIt != (hostIt->second).end()) {
        } else {
            (hostIt->second).push_back(srcPort);
            srcPortNum[timeBin][odPair] += 1;
        }
    } else {
        // host not yet in Map -> add it
        // create new port list
        PortList srcPortList(srcPort);
        srcPortMap.insert ( pair<int, PortList>(odPair, srcPortList) );
        srcPortNum[timeBin][odPair] = 1;
    }
    
    // **** destination port
    dstPort = ntohs(conn->dstPort);
    hostIt = dstPortMap.find(odPair);
    if(hostIt != dstPortMap.end()) {
        // host found in Map -> add port to vector
        PortListIterator portIt = find((hostIt->second).begin(), (hostIt->second).end(), dstPort);
        if (portIt != (hostIt->second).end()) {
        } else {
            (hostIt->second).push_back(dstPort);
            dstPortNum[timeBin][odPair] += 1;
        }
    } else {
        // host not yet in Map -> add it
        // create new port list
        PortList dstPortList(dstPort);
        dstPortMap.insert ( pair<int, PortList>(odPair, dstPortList) );
        dstPortNum[timeBin][odPair] = 1;
    }

}
Exemplo n.º 4
0
/******************************************************************************
** 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*/