double calculateJointEntropy(double *firstVector, double *secondVector, int vectorLength)
{
  double jointEntropy = 0.0;  
  double tempValue = 0.0;
  int i;
  JointProbabilityState state = calculateJointProbability(firstVector,secondVector,vectorLength);
  
  /*H(XY) = - sumx sumy p(xy) log p(xy)*/
  for (i = 0; i < state.numJointStates; i++)
  {
    tempValue = state.jointProbabilityVector[i];
    if (tempValue > 0)
    {
      jointEntropy -= tempValue * log(tempValue);
    }
  }
  
  jointEntropy /= log(2.0);
  
  FREE_FUNC(state.firstProbabilityVector);
  state.firstProbabilityVector = NULL;
  FREE_FUNC(state.secondProbabilityVector);
  state.secondProbabilityVector = NULL;
  FREE_FUNC(state.jointProbabilityVector);
  state.jointProbabilityVector = NULL;
  
  return jointEntropy;
}/*calculateJointEntropy(double *, double *, int)*/
Beispiel #2
0
double calculateMutualInformation(double *dataVector, double *targetVector, int vectorLength)
{
    double mutualInformation = 0.0;
    int firstIndex,secondIndex;
    int i;
    JointProbabilityState state = calculateJointProbability(dataVector,targetVector,vectorLength);

    /*
    ** I(X;Y) = sum sum p(xy) * log (p(xy)/p(x)p(y))
    */
    for (i = 0; i < state.numJointStates; i++)
    {
        firstIndex = i % state.numFirstStates;
        secondIndex = i / state.numFirstStates;

        if ((state.jointProbabilityVector[i] > 0) && (state.firstProbabilityVector[firstIndex] > 0) && (state.secondProbabilityVector[secondIndex] > 0))
        {
            /*double division is probably more stable than multiplying two small numbers together
            ** mutualInformation += state.jointProbabilityVector[i] * log(state.jointProbabilityVector[i] / (state.firstProbabilityVector[firstIndex] * state.secondProbabilityVector[secondIndex]));
            */
            mutualInformation += state.jointProbabilityVector[i] * log(state.jointProbabilityVector[i] / state.firstProbabilityVector[firstIndex] / state.secondProbabilityVector[secondIndex]);
        }
    }

    mutualInformation /= log(2.0);

    FREE_FUNC(state.firstProbabilityVector);
    state.firstProbabilityVector = NULL;
    FREE_FUNC(state.secondProbabilityVector);
    state.secondProbabilityVector = NULL;
    FREE_FUNC(state.jointProbabilityVector);
    state.jointProbabilityVector = NULL;

    return mutualInformation;
}/*calculateMutualInformation(double *,double *,int)*/
double calculateJointRenyiEntropy(double alpha, double *firstVector, double *secondVector, int vectorLength)
{
    double jointEntropy = 0.0;
    double tempValue = 0.0;
    int i;
    JointProbabilityState state = calculateJointProbability(firstVector,secondVector,vectorLength);

    /*H_\alpha(XY) = 1/(1-alpha) * log(2)(sum p(xy)^alpha)*/
    for (i = 0; i < state.numJointStates; i++)
    {
        tempValue = state.jointProbabilityVector[i];
        if (tempValue > 0)
        {
            jointEntropy += pow(tempValue,alpha);
        }
    }

    jointEntropy = log(jointEntropy);

    jointEntropy /= log(2.0);

    jointEntropy /= (1.0-alpha);

    FREE_FUNC(state.firstProbabilityVector);
    state.firstProbabilityVector = NULL;
    FREE_FUNC(state.secondProbabilityVector);
    state.secondProbabilityVector = NULL;
    FREE_FUNC(state.jointProbabilityVector);
    state.jointProbabilityVector = NULL;

    return jointEntropy;
}/*calculateJointRenyiEntropy(double,double*,double*,int)*/
Beispiel #4
0
double calcJointEntropy(uint *firstVector, uint *secondVector, int vectorLength) {
    JointProbabilityState state = calculateJointProbability(firstVector, secondVector, vectorLength);
    double h = jointEntropy(state);

    freeJointProbabilityState(state);

    return h;
}/*calcJointEntropy(uint *, uint *, int)*/
Beispiel #5
0
double calcConditionalEntropy(uint *dataVector, uint *conditionVector, int vectorLength) {
    JointProbabilityState state = calculateJointProbability(dataVector, conditionVector, vectorLength);
    double h = condEntropy(state);

    freeJointProbabilityState(state);

    return h;
}/*calcConditionalEntropy(uint *, uint *, int)*/
double calculateConditionalEntropy(double *dataVector, double *conditionVector, int vectorLength)
{
  /*
  ** Conditional entropy
  ** H(X|Y) = - sumx sumy p(xy) log p(xy)/p(y)
  */
  
  double condEntropy = 0.0;  
  double jointValue = 0.0;
  double condValue = 0.0;
  int i;
  JointProbabilityState state = calculateJointProbability(dataVector,conditionVector,vectorLength);
  
  /*H(X|Y) = - sumx sumy p(xy) log p(xy)/p(y)*/
  /* to index by numFirstStates use modulus of i
  ** to index by numSecondStates use integer division of i by numFirstStates
  */
  for (i = 0; i < state.numJointStates; i++)
  {
    jointValue = state.jointProbabilityVector[i];
    condValue = state.secondProbabilityVector[i / state.numFirstStates];
    if ((jointValue > 0) && (condValue > 0))
    {
      condEntropy -= jointValue * log(jointValue / condValue);
    }
  }
  
  condEntropy /= log(2.0);
  
  FREE_FUNC(state.firstProbabilityVector);
  state.firstProbabilityVector = NULL;
  FREE_FUNC(state.secondProbabilityVector);
  state.secondProbabilityVector = NULL;
  FREE_FUNC(state.jointProbabilityVector);
  state.jointProbabilityVector = NULL;
  
  return condEntropy;

}/*calculateConditionalEntropy(double *, double *, int)*/
Beispiel #7
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()*/