IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 35785 for trunk/psLib


Ignore:
Timestamp:
Jul 9, 2013, 6:36:20 PM (13 years ago)
Author:
watersc1
Message:

Fixed psMM errors in handling NAN values. I've added a wrapper function that censors these values before passing the valie data into the prior version of the functions. This is necessary as a mask won't work (there are matrix operations I don't want to bother sorting masking for).

Location:
trunk/psLib/src/math
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/psLib/src/math/psMixtureModels.c

    r35469 r35785  
    112112}
    113113
     114psImage *psMMCensorData(psImage *in,
     115                        long *Ncensored,
     116                        psVector *offsets) {
     117  // Allocate offset vector
     118  offsets = psVectorRecycle(offsets,in->numRows,PS_TYPE_S32);
     119
     120  *Ncensored = 0;
     121
     122  for (int i = 0; i < in->numRows; i++) {
     123    int isCensored = 0;
     124    for (int j = 0; j < in->numCols; j++) {
     125      if (!isfinite(in->data.F32[i][j])) {
     126        isCensored = 1;
     127      }
     128    }
     129    if (isCensored) {
     130      *Ncensored = *Ncensored + 1;
     131    }
     132    offsets->data.S32[i] = *Ncensored;
     133  }
     134  psImage *out;
     135  if (*Ncensored == 0) {
     136    out = psMemIncrRefCounter(in);
     137  }
     138  else {
     139    out = psImageAlloc(in->numCols,in->numRows - *Ncensored,PS_TYPE_F32);
     140    for (int i = 0; i < out->numRows; i++) {
     141      for (int j = 0; j < out->numCols; j++) {
     142        out->data.F32[i][j] = in->data.F32[i + offsets->data.S32[i]][j];
     143      }
     144    }
     145  }
     146  return(out);
     147}
    114148
    115149/////////////////////////////////////////////////////////////////////////////////
     
    117151/////////////////////////////////////////////////////////////////////////////////
    118152
    119 
    120153#define MAX_ITERATIONS 100
    121154#define THRESHOLD      1e-3
    122155
    123 
    124 bool psMMkmeans(psImage *D,
    125                 int dim,
    126                 long N,
    127                 psVector *modes,
    128                 psImage *means,
    129                 int m,
    130                 int *iterations,
    131                 double *V) {
     156bool psMMkmeans(psImage *D,      //< Input data to fit.                                         
     157                int dim,         //< dimension of the data                                       
     158                long N,          //< number of data points                                       
     159                psVector *modes, //< Output vector of which mode each data point belongs to     
     160                psImage *means,  //< Matrix containing mode mean values for each dimension       
     161                int m,           //< Number of modes to fit                                     
     162                int *iterations, //< Number of iterations to perform                             
     163                double *V) {     //< Deviation value.  Pseudo chi^2                           
     164  PS_ASSERT_IMAGE_NON_NULL(D,false);
     165  PS_ASSERT_IMAGE_TYPE(D,PS_TYPE_F32,false);
     166  // We need to scan the input for invalid d
     167  long Ncensored;
     168  psVector *offsets = psVectorAlloc(N,PS_TYPE_S32);
     169  psImage  *Dcensored = psMMCensorData(D,&Ncensored,offsets);
     170
     171  psVector *tempModes = psVectorAlloc(N - Ncensored,PS_TYPE_F32);
     172  bool success = psMMkmeansUncensored(Dcensored,
     173                                      dim,
     174                                      N - Ncensored,
     175                                      tempModes,
     176                                      means,
     177                                      m,
     178                                      iterations,
     179                                      V);
     180  if (Ncensored == 0) { // We can directly return the modes and means calculated
     181    if (modes) {
     182      psFree(modes);
     183    }
     184    modes = psMemIncrRefCounter(tempModes);
     185  }
     186  else {
     187    if (!modes) {
     188      modes = psVectorAlloc(N,PS_TYPE_F32);
     189    }
     190
     191    psVectorInit(modes,NAN);
     192    for (int i = 0; i < N - Ncensored; i++) {
     193      modes->data.F32[i - offsets->data.S32[i]] = tempModes->data.F32[i];
     194    }
     195  }
     196  psFree(offsets);
     197  psFree(Dcensored);
     198  psFree(tempModes);
     199  return(success);
     200}
     201
     202
     203bool psMMkmeansUncensored(psImage *D,       //< Input data to fit. 
     204                          int dim,          //< dimension of the data
     205                          long N,           //< number of data points
     206                          psVector *modes,  //< Output vector of which mode each data point belongs to
     207                          psImage *means,   //< Matrix containing mode mean values for each dimension
     208                          int m,            //< Number of modes to fit
     209                          int *iterations,  //< Number of iterations to perform
     210                          double *V) {      //< Deviation value.  Pseudo chi^2                           
    132211  // Assertions
    133212  PS_ASSERT_IMAGE_NON_NULL(D,false);
     
    135214  //  PS_ASSERT_IMAGE_SIZE(D,N,dim,false);
    136215
     216 
    137217  // Allocate things we can allocate here if they're not already allocated
    138218  if (!modes) {
    139     modes = psVectorAlloc(m,PS_TYPE_F32);
     219    modes = psVectorAlloc(N,PS_TYPE_F32);
    140220  }
    141221  if (!means) {
     
    277357}
    278358
    279 bool psMMGMM(psImage *D,
    280              int dim,
    281              long N,
    282              psVector *modes,
    283              psImage *means,
    284              psArray *sigma,
    285              psVector *pi,
    286              psImage *P,
    287              int m,
    288              int *iterations,
    289              double *V) {
     359bool psMMGMM(psImage *D,           //< Input data to fit
     360             int dim,              //< Dimension of each data vector
     361             long N,               //< Number of data vectors
     362             psVector *modes,      //< Output vector assigning each data point to a mode
     363             psImage *means,       //< Output matrix containing vectors of the means for each mode
     364             psArray *sigma,       //< Output array containing covariance matrices for each mode
     365             psVector *pi,         //< Output vector contining population fractions for each mode
     366             psImage *P,           //< Output matrix containing the probabilities a data point is in each mode
     367             int m,                //< Number of modes to fit
     368             int *iterations,      //< Number of iterations performed
     369             double *V) {          //< Log-likelihood of final solution.
     370
     371  PS_ASSERT_IMAGE_NON_NULL(D,false);
     372  PS_ASSERT_IMAGE_TYPE(D,PS_TYPE_F32,false);
     373  // We need to scan the input for invalid d
     374  long Ncensored;
     375  psVector *offsets = psVectorAlloc(N,PS_TYPE_F32);
     376  psImage  *Dcensored = psMMCensorData(D,&Ncensored,offsets);
     377
     378  psVector *tempModes = psVectorAlloc(N - Ncensored,PS_TYPE_F32);
     379  psImage  *tempP     = psImageAlloc(m,N - Ncensored,PS_TYPE_F32);
     380  bool success = psMMGMMUncensored(Dcensored,
     381                                   dim,
     382                                   N - Ncensored,
     383                                   tempModes,
     384                                   means,
     385                                   sigma,
     386                                   pi,
     387                                   tempP,
     388                                   m,
     389                                   iterations,
     390                                   V);
     391  if (Ncensored == 0) { // We can directly return the modes and means calculated
     392    if (modes) {
     393      psFree(modes);
     394    }
     395    if (P) {
     396      psFree(P);
     397    }
     398    modes = psMemIncrRefCounter(tempModes);
     399    P     = psMemIncrRefCounter(tempP);
     400  }
     401  else {
     402    if (!modes) {
     403      modes = psVectorAlloc(N,PS_TYPE_F32);
     404    }
     405    if (!P) {
     406      P = psImageAlloc(N,m,PS_TYPE_F32);
     407    }
     408    psVectorInit(modes,NAN);
     409    psImageInit(P,NAN);
     410
     411    for (int i = 0; i < N - Ncensored; i++) {
     412      modes->data.F32[i - offsets->data.S32[i]] = tempModes->data.F32[i];
     413      for (int j = 0; j < dim; j++) {
     414        P->data.F32[i - offsets->data.S32[i]][j] = tempP->data.F32[i][j];
     415      }
     416    }
     417  }
     418  psFree(offsets);
     419  psFree(Dcensored);
     420  psFree(tempModes);
     421  psFree(tempP);
     422  return(success);
     423}
     424
     425
     426bool psMMGMMUncensored(psImage *D,           //< Input data to fit
     427                       int dim,              //< Dimension of each data vector
     428                       long N,               //< Number of data vectors
     429                       psVector *modes,      //< Output vector assigning each data point to a mode
     430                       psImage *means,       //< Output matrix containing vectors of the means for each mode
     431                       psArray *sigma,       //< Output array containing covariance matrices for each mode
     432                       psVector *pi,         //< Output vector contining population fractions for each mode
     433                       psImage *P,           //< Output matrix containing the probabilities a data point is in each mode
     434                       int m,                //< Number of modes to fit
     435                       int *iterations,      //< Number of iterations performed
     436                       double *V) {          //< Log-likelihood of final solution.
    290437  // Assertions
    291438  PS_ASSERT_IMAGE_NON_NULL(D,false);
  • trunk/psLib/src/math/psMixtureModels.h

    r35394 r35785  
    22#define PS_MIXTUREMODELS_H
    33
     4// These are the recommended functions to call.  They in turn call code
     5// that scans the input data matrix/image and censored data points with
     6// non-finite values.  The censored data is then passed to the next set
     7// of functions.
    48
    59bool psMMkmeans(psImage *D,
     
    2428             double *V);
    2529
     30// These functions assume that the input data matrix/image is cleaned of
     31// non-finite values.  They should work identically as the ones above on
     32// data that is well defined.
     33bool psMMkmeansUncensored(psImage *D,
     34                          int dim,
     35                          long N,
     36                          psVector *modes,
     37                          psImage *means,
     38                          int m,
     39                          int *iterations,
     40                          double *V);
     41
     42bool psMMGMMUncensored(psImage *D,
     43                       int dim,
     44                       long N,
     45                       psVector *modes,
     46                       psImage *means,
     47                       psArray *sigma,
     48                       psVector *pi,
     49                       psImage *P,
     50                       int m,
     51                       int *iterations,
     52                       double *V);
     53
     54// This function does the classification in five stages:
     55//  1) pass data to K-means code with m modes for initial values.
     56//  2) pass data+K-mean values to GMM code with m modes for best values.
     57//  3) repeat K-means pass with m-1 modes.
     58//  4) repeat GMM pass with m-1 modes.
     59//  5) calculate Pvalue that the model with m modes is better than that with m-1
    2660bool psMMClass(psImage *D,
    2761               int dim,
     
    3468               int m,
    3569               double *Pval);
    36  
     70
     71
     72// These functions are one dimensional equivalent wrappers of the above functions.
     73// The psVector data is inserted into the appropriate sized psImage structure to
     74// avoid having to do so in each program calling this library.  Since this is the
     75// only special case (2-dim is a matrix, n-dim is matrix as well), no other wrappers
     76// are needed.
    3777bool psMM1Dkmeans(psVector *D,
    3878                  long N,
Note: See TracChangeset for help on using the changeset viewer.