NPclassify2.C

Go to the documentation of this file.
00001 /*!@file VFAT/NPclassify2.C  Test the nonparametric classifier
00002  */
00003 
00004 // //////////////////////////////////////////////////////////////////// //
00005 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the //
00006 // University of Southern California (USC) and the iLab at USC.         //
00007 // See http://iLab.usc.edu for information about this project.          //
00008 // //////////////////////////////////////////////////////////////////// //
00009 // Major portions of the iLab Neuromorphic Vision Toolkit are protected //
00010 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency //
00011 // in Visual Environments, and Applications'' by Christof Koch and      //
00012 // Laurent Itti, California Institute of Technology, 2001 (patent       //
00013 // pending; application number 09/912,225 filed July 23, 2001; see      //
00014 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status).     //
00015 // //////////////////////////////////////////////////////////////////// //
00016 // This file is part of the iLab Neuromorphic Vision C++ Toolkit.       //
00017 //                                                                      //
00018 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can   //
00019 // redistribute it and/or modify it under the terms of the GNU General  //
00020 // Public License as published by the Free Software Foundation; either  //
00021 // version 2 of the License, or (at your option) any later version.     //
00022 //                                                                      //
00023 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope  //
00024 // that it will be useful, but WITHOUT ANY WARRANTY; without even the   //
00025 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
00026 // PURPOSE.  See the GNU General Public License for more details.       //
00027 //                                                                      //
00028 // You should have received a copy of the GNU General Public License    //
00029 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write   //
00030 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,   //
00031 // Boston, MA 02111-1307 USA.                                           //
00032 // //////////////////////////////////////////////////////////////////// //
00033 //
00034 // Primary maintainer for this file: T Nathan Mundhenk <mundhenk@usc.edu>
00035 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/VFAT/NPclassify2.C $
00036 // $Id: NPclassify2.C 9412 2008-03-10 23:10:15Z farhan $
00037 //
00038 
00039 // ############################################################
00040 // ############################################################
00041 // ##### --- VFAT ---
00042 // ##### Vision Feature Analysis Tool:
00043 // ##### T. Nathan Mundhenk nathan@mundhenk.com
00044 // ##### Laurent Itt itti@pollux.usc.edu
00045 // #####
00046 // ############################################################
00047 // ############################################################
00048 
00049 /* This is a non-parametric unsupervised  classifier for use in the
00050    future with kubists. It takes as an input data points in n dimentions.
00051    classification is done in a clustering meathod by finding for any point
00052    whats its local density is then linking that point to the next closest
00053    point that has a higher density rating. Class boundry is created by
00054    "snipping" links that are for instance too long. This meathod has the
00055    advantage of being non-parametric. It makes no assumptions about data
00056    distribution (per se) or how many classes may exist. By taking the
00057    nearest point of highest density it can also distinguish between two
00058    incidentally connected classes e.g. two classes that are clustered close
00059    together.
00060    Complexity is D*n^2
00061 */
00062 
00063 #include "VFAT/NPclassify2.H"
00064 
00065 #include "Util/Assert.H"
00066 #include "Util/Timer.H"
00067 #include "Util/log.H"
00068 #include <fstream>
00069 #include <iostream>
00070 #include <math.h>
00071 
00072 /************************************************************************/
00073 // *****************************************
00074 // PUBLIC METHODS
00075 // *****************************************
00076 /************************************************************************/
00077 template <class FLOAT>
00078 NPclassify2<FLOAT>::NPclassify2(readConfig &settings, readConfig &polySet,
00079                        bool commandLineSettings)
00080 {
00081   NPsetup(settings,polySet,commandLineSettings);
00082 }
00083 
00084 /************************************************************************/
00085 
00086 template <class FLOAT>
00087 NPclassify2<FLOAT>::NPclassify2()
00088 {}
00089 
00090 /************************************************************************/
00091 
00092 template <class FLOAT>
00093 NPclassify2<FLOAT>::~NPclassify2()
00094 {}
00095 
00096 /***********************************************************************/
00097 
00098 template <class FLOAT>
00099 void NPclassify2<FLOAT>::NPsetup(readConfig &settings, readConfig &polySet,
00100                                  bool commandLineSettings)
00101 {
00102   NP_spaceSize = 0;
00103   NP_uspaceSize = 0;
00104   NP_stems = 0;
00105   NP_roots = 0;
00106   NP_lowDensCount = 0;
00107   // set up variables from config file
00108   NP_CLS = commandLineSettings;
00109   LINFO("SETTING NPclassify variables from readConfig");
00110   NP_defaultSize = (int)settings.getItemValueF("defaultSize");
00111   NP_Con1 = settings.getItemValueF("Con1");
00112   NP_Con2 = settings.getItemValueF("Con2");
00113   NP_Con3 = settings.getItemValueF("Con3");
00114   NP_hardClassSize = (int)settings.getItemValueF("hardClassSize");
00115   NP_hardLinkSize = (int)settings.getItemValueF("hardLinkSize");
00116   NP_DWeight1 = settings.getItemValueF("DWeight1");
00117   NP_DWeight2 = settings.getItemValueF("DWeight2");
00118   NP_CWeight1 = settings.getItemValueF("CWeight1");
00119   NP_CWeight2 = settings.getItemValueF("CWeight2");
00120 
00121   NP_IDWeight1 = settings.getItemValueF("IDWeight1");
00122   NP_IDWeight2 = settings.getItemValueF("IDWeight2");
00123   NP_ICWeight1 = settings.getItemValueF("ICWeight1");
00124   NP_ICWeight2 = settings.getItemValueF("ICWeight2");
00125   NP_DenWeight1 = settings.getItemValueF("DenWeight1");
00126   NP_DenWeight2 = settings.getItemValueF("DenWeight2");
00127   NP_preDenWeight1 = settings.getItemValueF("preDenWeight1");
00128   NP_preDenWeight2 = settings.getItemValueF("preDenWeight2");
00129   NP_enthardClassSize = settings.getItemValueF("enthardClassSize");
00130   NP_enthardLinkSize = settings.getItemValueF("enthardLinkSize");
00131   NP_entDWeight1 = settings.getItemValueF("entDWeight1");
00132   NP_entDWeight2 = settings.getItemValueF("entDWeight2");
00133   NP_entCWeight1 = settings.getItemValueF("entCWeight1");
00134   NP_entCWeight2 = settings.getItemValueF("entCWeight2");
00135   NP_entIDWeight1 = settings.getItemValueF("entIDWeight1");
00136   NP_entIDWeight2 = settings.getItemValueF("entIDWeight2");
00137   NP_entICWeight1 = settings.getItemValueF("entICWeight1");
00138   NP_entICWeight2 = settings.getItemValueF("entICWeight2");
00139   NP_entDenWeight1 = settings.getItemValueF("entDenWeight1");
00140   NP_entDenWeight2 = settings.getItemValueF("entDenWeight2");
00141   NP_entpreDenWeight1 = settings.getItemValueF("entpreDenWeight1");
00142   NP_entpreDenWeight2 = settings.getItemValueF("entpreDenWeight2");
00143 
00144   NP_trainChildWeight = settings.getItemValueF("trainChildWeight");
00145   NP_doLinkMap = (int)settings.getItemValueF("doLinkMap");
00146   NP_doDensityMap = (int)settings.getItemValueF("doDensityMap");
00147   NP_doClassMap = (int)settings.getItemValueF("doClassMap");
00148   NP_usePolySet = (int)settings.getItemValueF("usePolySet");
00149   LINFO("SETTING kernel poly variables from polySet");
00150   NP_polyDensObjectCut1 = polySet.getItemValueF("polyDensObjectCut1");
00151   NP_polyDensObjectCut2 = polySet.getItemValueF("polyDensObjectCut2");
00152   NP_polyDensObjectCut3 = polySet.getItemValueF("polyDensObjectCut3");
00153   NP_polySpaceChildCut1 = polySet.getItemValueF("polySpaceChildCut1");
00154   NP_polySpaceChildCut2 = polySet.getItemValueF("polySpaceChildCut2");
00155   NP_polySpaceChildCut3 = polySet.getItemValueF("polySpaceChildCut3");
00156   LINFO("DONE");
00157   // set up vectors to a reasonable initial size
00158   //NPresizeSpace();
00159   // zero some initial counters
00160   //NPresetSpace();
00161 }
00162 
00163 /************************************************************************/
00164 
00165 template <class FLOAT>
00166 void NPclassify2<FLOAT>::NPinputCommandLineSettings(FLOAT inVals[31])
00167 {
00168   NP_DWeight1           = inVals[0]; /*used*/
00169   NP_DWeight2           = inVals[1]; /*used*/
00170   NP_CWeight1           = inVals[2]; /*used*/
00171   NP_CWeight2           = inVals[3]; /*used*/
00172   NP_hardClassSize      = (int)inVals[4]; /*used*/
00173   NP_hardLinkSize       = (int)inVals[5]; /*used*/
00174   NP_IDWeight1          =  inVals[6]; /*used*/
00175   NP_IDWeight2          = inVals[7]; /*used*/
00176   NP_ICWeight1          = inVals[8]; /*used*/
00177   NP_ICWeight2          = inVals[9]; /*NOT used*/
00178   NP_DenWeight1         = inVals[10]; /*used*/
00179   NP_DenWeight2         = inVals[11]; /*NOT used*/
00180   NP_preDenWeight1      = inVals[12]; /*NOT used*/
00181   NP_preDenWeight2      = inVals[13]; /*NOT used*/
00182   NP_polyDensObjectCut1 = inVals[14]; /*used*/
00183   NP_polyDensObjectCut2 = inVals[15]; /*used*/
00184   NP_polyDensObjectCut3 = inVals[16]; /*used*/
00185 
00186   NP_entDWeight1        = inVals[17]; /*used*/
00187   NP_entDWeight2        = inVals[18]; /*used*/
00188   NP_entCWeight1        = inVals[19]; /*used*/
00189   NP_entCWeight2        = inVals[20]; /*used*/
00190   NP_enthardClassSize   = inVals[21]; /*used*/
00191   NP_enthardLinkSize    = inVals[22]; /*used*/
00192   NP_entIDWeight1       = inVals[23]; /*used*/
00193   NP_entIDWeight2       = inVals[24]; /*used*/
00194   NP_entICWeight1       = inVals[25]; /*used*/
00195   NP_entICWeight2       = inVals[26]; /*NOT used*/
00196   NP_entDenWeight1      = inVals[27]; /*used*/
00197   NP_entDenWeight2      = inVals[28]; /*used*/
00198   NP_entpreDenWeight1   = inVals[29];  /*NOT used*/
00199   NP_entpreDenWeight2   = inVals[30];  /*NOT used*/
00200 }
00201 
00202 /************************************************************************/
00203 
00204 template <class FLOAT>
00205 void NPclassify2<FLOAT>::NPaddPoint(std::vector<int> point)
00206 {
00207   //FOO
00208 }
00209 
00210 /************************************************************************/
00211 
00212 template <class FLOAT>
00213 void NPclassify2<FLOAT>::NPaddSpace(typename
00214                                     std::vector<std::vector<FLOAT> > &space)
00215 {
00216   NP_Space = &space;
00217 }
00218 
00219 /************************************************************************/
00220 
00221 template <class FLOAT>
00222 void NPclassify2<FLOAT>::NPechoSpace()
00223 {
00224   for(int i = 0; i < NP_spaceSize; i++)
00225   {
00226     std::cerr << i << " ";
00227     for(unsigned int j = 0; j < NP_Space->at(i).size(); j++)
00228       std::cerr << NP_Space->at(i)[j] << " ";
00229     std::cerr << "\n";
00230   }
00231 }
00232 
00233 /************************************************************************/
00234 
00235 template <class FLOAT>
00236 void NPclassify2<FLOAT>::NPresetSpace(int features, int dims)
00237 {
00238   std::cerr << "SPACE RESET new size " << features << " x " << dims << "\n";
00239   NP_stems        = 0;
00240   NP_roots        = 0;
00241   NP_lowDensCount = 0;
00242   NP_useBias      = false;
00243   for(int i = 0; i < NP_spaceSize; i++)
00244   {
00245     NP_classSize[i] = 0;
00246     NP_decCount[i]  = 0;
00247     NP_children[i]  = 0;
00248     NP_distance[i]  = 0.0F;
00249     NP_density[i]   = 0.0F;
00250     NP_entropy[i]   = 0.0F;
00251     NP_predCount[i] = 0;
00252     NP_master[i]    = &NP_ZERO;
00253     NP_masterIndexCount[i] = 0;
00254     NP_subDecCount[i]      = 0;
00255 
00256   }
00257   NP_spaceSize = 0;  NP_uspaceSize = 0;
00258   NPparamSpace(features,dims);
00259 }
00260 
00261 /************************************************************************/
00262 
00263 template <class FLOAT>
00264 void NPclassify2<FLOAT>::NPresetSpace()
00265 {
00266   std::cerr << "SPACE RESET\n";
00267   NP_stems = 0;
00268   NP_roots = 0;
00269   NP_lowDensCount = 0;
00270   NP_useBias = false;
00271   for(int i = 0; i < NP_spaceSize; i++)
00272   {
00273     NP_classSize[i] = 0;
00274     NP_decCount[i]  = 0;
00275     NP_children[i] = 0;
00276     NP_density[i] = 0.0F;
00277     NP_entropy[i] = 0.0F;
00278     NP_distance[i] = 0.0F;
00279     NP_predCount[i] = 0;
00280     NP_master[i] = &NP_ZERO;
00281     NP_masterIndexCount[i] = 0;
00282     NP_subDecCount[i] = 0;
00283   }
00284 }
00285 
00286 /************************************************************************/
00287 template <class FLOAT>
00288 void NPclassify2<FLOAT>::NPsetConvolveBias(
00289                             std::vector<covHolder<double> > *ch,
00290                             int listSize,
00291                             FLOAT bias)
00292 {
00293   NP_useBias       = true;
00294   NP_biasWeight    = bias;
00295   NP_covHolder     = ch;
00296   NP_covHolderSize = listSize;
00297 }
00298 
00299 /************************************************************************/
00300 
00301 template <class FLOAT>
00302 void NPclassify2<FLOAT>::NPclassifySpaceNew(bool doBias = true)
00303 {
00304   std::cerr << "SPACE SIZE = " << NP_spaceSize << "\n";
00305   Timer tim;
00306   tim.reset();
00307   int t1,t2;
00308   int t0 = tim.get();  // to measure display time
00309   std::cerr << "\tTIME: " << t0 << "ms\n";
00310   std::cerr << "CONVOLVE SPACE\n";
00311   NPconvolveSpace();
00312   t1 = tim.get();
00313   t2 = t1 - t0;
00314   std::cerr << "\tTIME: " << t2 << "ms\n";
00315   if((NP_useBias == true) && (doBias == true))
00316   {
00317     std::cerr << "BIAS SPACE\n";
00318     NPbiasConvolveSpace();
00319     t1 = tim.get();
00320     t2 = t1 - t0;
00321     std::cerr << "\tTIME: " << t2 << "ms\n";
00322   }
00323   std::cerr << "LINK SPACE\n";
00324   NPlinkSpace();
00325   t1 = tim.get();
00326   t2 = t1 - t0;
00327   std::cerr << "\tTIME: "<< t2 << "ms\n";
00328   std::cerr << "MAP SPACE\n";
00329   NPmapSpace();
00330   t1 = tim.get();
00331   t2 = t1 - t0;
00332   std::cerr << "\tTIME: "<< t2 << "ms\n";
00333   std::cerr << "ANALYZE SPACE\n";
00334   NPanalizeSpace();
00335   t1 = tim.get();
00336   t2 = t1 - t0;
00337   std::cerr << "\tTIME: "<< t2 << "ms\n";
00338   std::cerr << "EVOLVE SPACE\n";
00339   NPevolveSpace();
00340   t1 = tim.get();
00341   t2 = t1 - t0;
00342   std::cerr << "\tTIME: "<< t2 << "ms\n";
00343   std::cerr << "ANALYZE INTER SPACE\n";
00344   NPanalizeInterSpace();
00345   t1 = tim.get();
00346   t2 = t1 - t0;
00347   std::cerr << "\tTIME: "<< t2 << "ms\n";
00348   std::cerr << "EVOLVE INTER SPACE\n";
00349   NPevolveInterSpace();
00350   t1 = tim.get();
00351   t2 = t1 - t0;
00352   std::cerr << "\tTIME: "<< t2 << "ms\n";
00353   std::cerr << "ANALYZE CLASS DENSITY\n";
00354   NPanalizeClassDensity();
00355   t1 = tim.get();
00356   t2 = t1 - t0;
00357   std::cerr << "\tTIME: "<< t2 << "ms\n";
00358 }
00359  /************************************************************************/
00360 
00361 template <class FLOAT>
00362 FLOAT NPclassify2<FLOAT>::NPclassifySpaceKmeans(unsigned int *K,
00363                                                 FLOAT *minDiff,
00364                                                 unsigned int *stopIter)
00365 {
00366   // set this for consistancy with other methods
00367   NP_stems = *K;
00368   // counter for iterations
00369   int iter = 0;
00370   // holds Kmean values
00371   typename std::vector<FLOAT> tempVec(NP_dimSize,0.0F);
00372   NP_Kmean.resize(*K,tempVec);
00373 
00374   LINFO("KMEAN - Space resized");
00375   //first assign everyone to a random class
00376   FLOAT temp;
00377   temp = *K;
00378   LINFO("classes %f",temp);
00379   for(int i = 0; i < NP_spaceSize; i++)
00380   {
00381     int tempClass  = (int)((temp*rand())/(RAND_MAX+1.0F));
00382     int *classsize = &NP_classSize[tempClass];
00383     NP_Class[tempClass][*classsize] = &NP_keyVal[i];
00384     *classsize     = *classsize+1;
00385     NP_master[i]   = &NP_keyVal[tempClass];
00386   }
00387   LINFO("KMEAN - Random classes assigned");
00388   //iterate until convergance
00389   bool doThis = true;
00390   FLOAT error = -1.0F;
00391 
00392   while(doThis)
00393   {
00394     //compute K mean
00395     LINFO("...KMEAN - Iteration %d",iter);
00396     for(int i = 0; i < (signed)*K; i++)
00397     {
00398       int *classsize = &NP_classSize[i];
00399       if(*classsize > 0)
00400       {
00401         for(int d = 0; d < NP_dimSize; d++)
00402         {
00403           FLOAT num = 0;
00404           for(int j = 0; j < *classsize; j++)
00405           {
00406             num += NP_Space->at(*NP_Class[i][j])[d];
00407           }
00408           NP_Kmean[i][d] = num/(*classsize);
00409         }
00410       }
00411     }
00412     LINFO("...KMEAN - Means Calculated");
00413     std::vector<int> tempClassSize(*K,0);
00414     FLOAT tempError = 0;
00415     // compute distance from points to each K mean
00416     for(int ix = 0; ix < NP_spaceSize; ix++)
00417     {
00418       //iterate over every point to the means
00419       for(int iy = 0; iy < (signed)*K; iy++)
00420       {
00421         FLOAT *npdis = &NP_Dis[ix][iy];
00422         *npdis = 0;
00423         // get distance between point and k-mean
00424         for(int px = 0; px < NP_dimSize; px++)
00425         {
00426           *npdis = *npdis +
00427             pow((NP_Space->at(ix)[px] - NP_Kmean[iy][px]),2);
00428         }
00429         *npdis = sqrt(*npdis);
00430       }
00431 
00432       // find error (the sum of all distances from any point to it's
00433       // class mean
00434       tempError += NP_Dis[ix][*NP_master[ix]];
00435     }
00436     LINFO("...KMEAN - Distance to Means Checked ERROR %f",tempError);
00437     // check error v. previous error
00438     // run if error is still high or iterations have not been surpassed
00439     // and if it is the first iteration, always run.
00440     if(((error < 0) || ((error - tempError) > *minDiff)) &&
00441        (iter < (signed)*stopIter))
00442     {
00443       for(int ix = 0; ix < NP_spaceSize; ix++)
00444       {
00445         int *np_master = NP_master[ix];
00446         // re-assign me to a new k-mean class
00447         for(int iy = 0; iy < (signed)*K; iy++)
00448         {
00449           NP_classSize[*K] = 0;
00450           if(NP_Dis[ix][iy] < NP_Dis[ix][*np_master])
00451           {
00452             np_master = &NP_keyVal[iy];
00453           }
00454         }
00455         //re-build class list
00456         NP_Class[*np_master][tempClassSize[*np_master]] = &NP_keyVal[ix];
00457         NP_classIndex[ix] = np_master;
00458         tempClassSize[*np_master]++;
00459       }
00460       // resize the classes for all the new points
00461       for(int iy = 0; iy < (signed)*K; iy++)
00462       {
00463         NP_classSize[iy] = tempClassSize[iy];
00464       }
00465       iter++;
00466     }
00467     else
00468     {
00469       doThis = false;
00470     }
00471   }
00472   return error;
00473 }
00474 
00475 
00476 /************************************************************************/
00477 
00478 template <class FLOAT>
00479 void NPclassify2<FLOAT>::NPclassifySpacePartial()
00480 {}
00481 
00482 /************************************************************************/
00483 
00484 template <class FLOAT>
00485 int NPclassify2<FLOAT>::NPgetStemNumber()
00486 {
00487   return NP_stems;
00488 }
00489 
00490 /************************************************************************/
00491 
00492 template <class FLOAT>
00493 int NPclassify2<FLOAT>::NPgetStemNumberEdit()
00494 {
00495   int min = 0;
00496   for(int i = 0; i < NPgetStemNumber(); i++)
00497   {
00498     if(NPgetClassSize(i) > NPgetMinClassSize())
00499     {
00500       min++;
00501     }
00502   }
00503   return min;
00504 }
00505 
00506 /************************************************************************/
00507 
00508 template <class FLOAT>
00509 FLOAT NPclassify2<FLOAT>::NPgetMaxDensity()
00510 {
00511   return NP_maxDensity;
00512 }
00513 
00514 /************************************************************************/
00515 
00516 template <class FLOAT>
00517 FLOAT NPclassify2<FLOAT>::NPgetMeanDensity()
00518 {
00519   return NP_meanDensity;
00520 }
00521 
00522 /************************************************************************/
00523 
00524 template <class FLOAT>
00525 FLOAT NPclassify2<FLOAT>::NPgetStdDensity()
00526 {
00527   return NP_stdDensity;
00528 }
00529 
00530 /************************************************************************/
00531 
00532 template <class FLOAT>
00533 typename std::vector<FLOAT>* NPclassify2<FLOAT>::NPgetMeanClassDensity()
00534 {
00535   return &NP_meanClassDensity;
00536 }
00537 
00538 /************************************************************************/
00539 
00540 template <class FLOAT>
00541 typename std::vector<FLOAT>* NPclassify2<FLOAT>::NPgetStdClassDensity()
00542 {
00543   return &NP_stdClassDensity;
00544 }
00545 
00546 /************************************************************************/
00547 
00548 template <class FLOAT>
00549 FLOAT NPclassify2<FLOAT>::NPgetEntropy()
00550 {
00551   return NP_totalEntropy;
00552 }
00553 
00554 /************************************************************************/
00555 
00556 template <class FLOAT>
00557 bool NPclassify2<FLOAT>::NPisLowDensity(int item)
00558 {
00559   return NP_lowDensity[item];
00560 }
00561 
00562 /************************************************************************/
00563 
00564 template <class FLOAT>
00565 bool NPclassify2<FLOAT>::NPisStem(int item)
00566 {
00567   return NP_revStem[item];
00568 }
00569 
00570 /************************************************************************/
00571 
00572 template <class FLOAT>
00573 std::vector<FLOAT> NPclassify2<FLOAT>::NPgetDensity()
00574 {
00575   return NP_density;
00576 }
00577 
00578 /************************************************************************/
00579 
00580 template <class FLOAT>
00581 std::vector<FLOAT>* NPclassify2<FLOAT>::NPgetDensityPtr()
00582 {
00583   return &NP_density;
00584 }
00585 
00586 /************************************************************************/
00587 
00588 template <class FLOAT>
00589 std::vector<int*> NPclassify2<FLOAT>::NPgetStems()
00590 {
00591   return NP_stem;
00592 }
00593 
00594 /************************************************************************/
00595 
00596 template <class FLOAT>
00597 int NPclassify2<FLOAT>::NPgetClassSize(int _Class)
00598 {
00599   ASSERT((_Class <= (signed)NP_classSize.size()) && (_Class >= 0));
00600   return NP_classSize[_Class];
00601 }
00602 
00603 /************************************************************************/
00604 
00605 template <class FLOAT>
00606 int NPclassify2<FLOAT>::NPgetMinClassSize()
00607 {
00608   return NP_hardClassSize;
00609 }
00610 
00611 /************************************************************************/
00612 
00613 template <class FLOAT>
00614 std::vector<std::vector<int*> >* NPclassify2<FLOAT>::NPgetClass()
00615 {
00616   return &NP_Class;
00617 }
00618 
00619 /************************************************************************/
00620 
00621 template <class FLOAT>
00622 std::vector<int*> NPclassify2<FLOAT>::NPgetClass(int _Class)
00623 {
00624   ASSERT((_Class <= (signed)NP_Class.size()) && ((_Class >= 0)));
00625   return NP_Class[_Class];
00626 }
00627 
00628 /************************************************************************/
00629 
00630 template <class FLOAT>
00631 int NPclassify2<FLOAT>::NPgetClass(int _Class, int item)
00632 {
00633   ASSERT((_Class <= (signed)NP_Class.size()) && ((_Class >= 0)));
00634   ASSERT((item <= (signed)NP_Class[item].size()) && ((item >= 0)));
00635   return *NP_Class[_Class][item];
00636 }
00637 
00638 /************************************************************************/
00639 
00640 template <class FLOAT>
00641 FLOAT NPclassify2<FLOAT>::NPgetFeature(int m_feature_index, int n_vector_index)
00642 {
00643   ASSERT((m_feature_index <= (signed)NP_Space->size()) && (m_feature_index >= 0));
00644   ASSERT((n_vector_index <= (signed)NP_Space->at(m_feature_index).size())
00645          && (n_vector_index >= 0));
00646   return NP_Space->at(m_feature_index)[n_vector_index];
00647 }
00648 
00649 /************************************************************************/
00650 
00651 template <class FLOAT>
00652 std::vector<int*> NPclassify2<FLOAT>::NPgetParents()
00653 {
00654   return NP_parent;
00655 }
00656 
00657 /************************************************************************/
00658 
00659 template <class FLOAT>
00660 std::vector<std::vector<int*> > NPclassify2<FLOAT>::NPgetChildren()
00661 {
00662   return NP_childMap;
00663 }
00664 
00665 /************************************************************************/
00666 
00667 template <class FLOAT>
00668 std::vector<std::vector<int> > NPclassify2<FLOAT>::NPgetBoundingBoxes(
00669 bool ignore)
00670 {
00671   std::vector<int> box(4,0);
00672   std::vector<std::vector<int> > boundingBox(NP_stems,box);
00673 
00674 
00675   for(int ix = 0; ix < NP_spaceSize; ix++)
00676   {
00677     if((NP_revStem[ix] == false) || (ignore))
00678     {
00679       if((NP_lowDensity[ix] == false) || (ignore))
00680         //&& (classSize[classIndexIndex[ix]] > hardClassSize))
00681       {
00682         //std::cerr << *NP_classIndex[ix] << " " << ix << "\n";
00683         if(boundingBox[*NP_classIndex[ix]][0] == 0)
00684           boundingBox[*NP_classIndex[ix]][0] = (int)NP_Space->at(ix)[0];
00685         else
00686           if(boundingBox[*NP_classIndex[ix]][0] < NP_Space->at(ix)[0])
00687             boundingBox[*NP_classIndex[ix]][0] = (int)NP_Space->at(ix)[0];
00688         if(boundingBox[*NP_classIndex[ix]][1] == 0)
00689           boundingBox[*NP_classIndex[ix]][1] = (int)NP_Space->at(ix)[1];
00690         else
00691           if(boundingBox[*NP_classIndex[ix]][1] < NP_Space->at(ix)[1])
00692             boundingBox[*NP_classIndex[ix]][1] = (int)NP_Space->at(ix)[1];
00693         if(boundingBox[*NP_classIndex[ix]][2] == 0)
00694           boundingBox[*NP_classIndex[ix]][2] = (int)NP_Space->at(ix)[0];
00695         else
00696           if(boundingBox[*NP_classIndex[ix]][2] > NP_Space->at(ix)[0])
00697             boundingBox[*NP_classIndex[ix]][2] = (int)NP_Space->at(ix)[0];
00698         if(boundingBox[*NP_classIndex[ix]][3] == 0)
00699           boundingBox[*NP_classIndex[ix]][3] = (int)NP_Space->at(ix)[1];
00700         else
00701           if(boundingBox[*NP_classIndex[ix]][3] > NP_Space->at(ix)[1])
00702             boundingBox[*NP_classIndex[ix]][3] = (int)NP_Space->at(ix)[1];
00703       }
00704     }
00705   }
00706   return boundingBox;
00707 }
00708 
00709 /************************************************************************/
00710 
00711 template <class FLOAT>
00712 void NPclassify2<FLOAT>::NPdrawBoundingBoxes(
00713                                       std::vector<std::vector<int> > *BB,
00714                                       Image<PixRGB<FLOAT> > *ibox,
00715                                       int offsetX, int offsetY,
00716                                       PixRGB<FLOAT> pix, bool ignorMin)
00717 {
00718   LINFO("DRAWING %d STEMS",NPgetStemNumber());
00719   for(int i = 0; i < NPgetStemNumber(); i++)
00720   {
00721     if((NPgetClassSize(i) > NPgetMinClassSize()) || (ignorMin))
00722     {
00723       drawLine(*ibox, Point2D<int>(BB->at(i)[0]+offsetX,BB->at(i)[1]+offsetY),
00724                Point2D<int>(BB->at(i)[2]+offsetX,BB->at(i)[1]
00725                        +offsetY),pix,1);
00726       drawLine(*ibox, Point2D<int>(BB->at(i)[0]+offsetX,BB->at(i)[3]+offsetY),
00727                Point2D<int>(BB->at(i)[2]+offsetX,BB->at(i)[3]
00728                        +offsetY),pix,1);
00729 
00730       drawLine(*ibox, Point2D<int>(BB->at(i)[0]+offsetX,BB->at(i)[1]+offsetY),
00731                Point2D<int>(BB->at(i)[0]+offsetX,BB->at(i)[3]
00732                        +offsetY),pix,1);
00733       drawLine(*ibox, Point2D<int>(BB->at(i)[2]+offsetX,BB->at(i)[1]+offsetY),
00734                Point2D<int>(BB->at(i)[2]+offsetX,BB->at(i)[3]
00735                        +offsetY),pix,1);
00736       LINFO("DRAWING BOX for class %d size %d",i,NPgetClassSize(i));
00737     }
00738   }
00739 }
00740 
00741 /************************************************************************/
00742 
00743 template <class FLOAT>
00744 void NPclassify2<FLOAT>::NPmetaClassify(int objects)
00745 {
00746   // find the first n links that meet that training criteria
00747   // find their statistics
00748   // open file to save tab delim data to
00749   std::ofstream outfile("train_set.dat",std::ios::app);
00750 
00751   // create statistics
00752 
00753   for(unsigned int ix = 0; ix < NP_uspaceSize; ix++)
00754   {
00755     NP_trainMeasure[ix] = NP_distance[ix]*(NP_decCount[ix]/NP_trainChildWeight);
00756     NP_selected[ix] = false;
00757   }
00758 
00759   // find the n best candidates
00760   for(int n = 0; n < objects; n++)
00761   {
00762     int init = 0;
00763     for(unsigned int ix = 0; ix < NP_uspaceSize; ix++)
00764     {
00765       if(NP_selected[ix] == false)
00766       {
00767         if(init == 0)
00768         {
00769           NP_idealLinks[n] = ix;
00770           init = 1;
00771         }
00772         else
00773         {
00774           if(NP_trainMeasure[ix] > NP_trainMeasure[NP_idealLinks[n]])
00775           {
00776             NP_idealLinks[n] = ix;
00777           }
00778         }
00779       }
00780     }
00781     NP_selected[NP_idealLinks[n]] = true;
00782   }
00783 
00784   // find there stats as they apply to the current scene
00785   // find min child and distance for nodes
00786   int init = 0;
00787   for(int n = 0; n < objects; n++)
00788   {
00789     if(init == 0)
00790     {
00791       NP_minDist = NP_idealLinks[n];
00792       NP_minChild = NP_idealLinks[n];
00793       init = 1;
00794     }
00795     else
00796     {
00797       if(NP_distance[NP_idealLinks[n]] < NP_distance[NP_minDist])
00798       {
00799         NP_minDist = NP_idealLinks[n];
00800       }
00801       if(NP_decCount[NP_idealLinks[n]] <  NP_decCount[NP_minChild])
00802       {
00803         NP_minChild = NP_idealLinks[n];
00804       }
00805     }
00806   }
00807   int returnStems = NP_stems;
00808   for(int i = 0; i < NP_stems; i++)
00809   {
00810     if(NP_classSize[i] <= NP_hardClassSize)
00811     {
00812       --returnStems;
00813     }
00814   }
00815 
00816   NP_distanceCut = (NP_distance[NP_minDist] - NP_meanDistance)/NP_stdDistance;
00817   NP_childCut    = NP_decCount[NP_minChild]/NP_meanDecCount;
00818 
00819   outfile << NP_spaceSize << "\t" << NP_meanDensity << "\t"
00820           << objects << "\t" << NP_distanceCut << "\t"
00821           << NP_childCut << "\t" << returnStems << "\n";
00822 
00823   outfile.close();
00824 }
00825 
00826 /************************************************************************/
00827 
00828 template <class FLOAT>
00829 void NPclassify2<FLOAT>::NPdumpLinkInfo(std::string fileName)
00830 {
00831   // each sample carries these pieces of information as well as
00832   // larger maps which are not used here
00833   typename std::vector<FLOAT>::iterator idistance    = NP_distance.begin();
00834   typename std::vector<FLOAT>::iterator idensity     = NP_density.begin();
00835   typename std::vector<FLOAT>::iterator ientropy     = NP_entropy.begin();
00836   std::vector<int*>::iterator   iparent              = NP_parent.begin();
00837   std::vector<int*>::iterator   irevStemVal          = NP_revStemVal.begin();
00838   std::vector<int*>::iterator   iclassIndex          = NP_classIndex.begin();
00839   std::vector<bool>::iterator   irevStem             = NP_revStem.begin();
00840   std::vector<bool>::iterator   ilowDensity          = NP_lowDensity.begin();
00841   std::vector<int>::iterator    ipredCount           = NP_predCount.begin();
00842   std::vector<int>::iterator    ichildren            = NP_children.begin();
00843   std::vector<int>::iterator    idecCount            = NP_decCount.begin();
00844   std::string myName = "NPfeatures." + fileName + ".txt";
00845   std::ofstream outfile(myName.c_str(),std::ios::out);
00846   outfile << "BASE STATS:\n";
00847   outfile << "SpaceSize\tDimSize\tStems\tRoots\tMinDistance\t"
00848           << "MinChild\tLowDensityCount\tMaxDensity\tMeanDistance\t"
00849           << "StdDistance\tMeanDensity\tStdDensity\tMeanChild\t"
00850           << "StdChild\tMeanDecCount\tStdDecCount\n";
00851   outfile << NP_spaceSize    << "\t" << NP_dimSize      << "\t"
00852           << NP_stems        << "\t" << NP_roots        << "\t"
00853           << NP_minDist      << "\t" << NP_minChild     << "\t"
00854           << NP_lowDensCount << "\t" << NP_maxDensity   << "\t"
00855           << NP_meanDistance << "\t" << NP_stdDistance  << "\t"
00856           << NP_meanDensity  << "\t" << NP_stdDensity   << "\t"
00857           << NP_meanChild    << "\t" << NP_stdChildren  << "\t"
00858           << NP_meanDecCount << "\t" << NP_stdDecCount  << "\n";
00859 
00860   outfile << "SAMPLE STATS:\n";
00861   outfile << "Distance\tDensity\tEntropy\tParent\tRevStemVal\t"
00862           << "ClassIndex\tRevStem\tLowDensity\tPredCount\tChildren\t"
00863           << "DecCount\n";
00864   for(int ix = 0; ix < NP_spaceSize; ix++, ++idistance, ++idensity,
00865         ++ientropy, ++iparent, ++irevStemVal, ++irevStem, ++ilowDensity,
00866         ++ipredCount, ++ichildren, ++idecCount, ++iclassIndex)
00867   {
00868     outfile << *idistance    << "\t" << *idensity     << "\t"
00869             << *ientropy     << "\t" << **iparent     << "\t"
00870             << **irevStemVal << "\t" << **iclassIndex << "\t"
00871             << *irevStem     << "\t" << *ilowDensity  << "\t"
00872             << *ipredCount   << "\t" << *ichildren    << "\t"
00873             << *idecCount    << "\n";
00874   }
00875   outfile.close();
00876 }
00877 
00878 
00879 /************************************************************************/
00880 // *****************************************
00881 // PRIVATE METHODS
00882 // *****************************************
00883 /************************************************************************/
00884 
00885 template <class FLOAT>
00886 void NPclassify2<FLOAT>::NPconvolveSpace()
00887 {
00888   // find distance between all points as an n^2 alg. Sum these for all
00889   // points to determine a points density measure
00890   std::vector<int>::iterator  ichildren = NP_children.begin();
00891   std::vector<bool>::iterator irevStem  = NP_revStem.begin();
00892   typename std::vector<std::vector<FLOAT>  >::iterator iDis = NP_Dis.begin();
00893   typename std::vector<std::vector<FLOAT*> >::iterator irevDis
00894     = NP_reverseDisMap.begin();
00895   typename std::vector<std::vector<FLOAT> >::iterator iSpaceX
00896     = NP_Space->begin();
00897   typename std::vector<std::vector<FLOAT> >::iterator iSpaceY;
00898   typename std::vector<FLOAT>::iterator  idensity = NP_density.begin();
00899   typename std::vector<FLOAT>::iterator  iiSpaceX;
00900   typename std::vector<FLOAT>::iterator  iiSpaceY;
00901   typename std::vector<FLOAT>::iterator  iiDis;
00902   typename std::vector<FLOAT*>::iterator iirevDis;
00903 
00904   for(unsigned int ix = 0; ix < NP_uspaceSize; ix++,
00905         ++ichildren, ++irevStem, ++iDis,
00906         ++idensity, ++iSpaceX, ++irevDis)
00907   {
00908     *ichildren = 0;
00909     *irevStem = false;
00910     //iterate over every tupple, find distance, copy to symetric tupple
00911     iiDis    = iDis->begin()     + ix + 1;
00912     iirevDis = irevDis->begin()  + ix + 1;
00913     iSpaceY  = NP_Space->begin() + ix + 1;
00914     for(unsigned int iy = ix+1; iy < NP_uspaceSize; iy++, ++iiDis, ++iSpaceY,
00915         ++iirevDis)
00916     {
00917       *iiDis   = 0;
00918       iiSpaceX = iSpaceX->begin();
00919       iiSpaceY = iSpaceY->begin();
00920       // get distance between these two points
00921       for(unsigned int px = 0; px < NP_udimSize; px++, ++iiSpaceX, ++iiSpaceY)
00922       {
00923         *iiDis = *iiDis + pow((*iiSpaceX - *iiSpaceY),2);
00924       }
00925       **iirevDis = *iiDis;
00926     }
00927 
00928     // find distance as sqrt(sum(sqared distances))
00929     // take the inverse distance 1/D
00930     iiDis = iDis->begin();
00931     for(unsigned int iy = 0; iy < NP_uspaceSize; iy++, ++iiDis)
00932     {
00933       if(*iiDis != 0)
00934         *idensity = (1/sqrt(*iiDis))+(*idensity);
00935     }
00936   }
00937 }
00938 
00939 /************************************************************************/
00940 
00941 template <class FLOAT>
00942 void NPclassify2<FLOAT>::NPconvolveSpace(long item)
00943 {
00944   // find distance between all points as an n alg. Sum these for all
00945   // points to determine a points density measure
00946 
00947   NP_children[item] = 0;
00948   NP_revStem[item]  = false;
00949 
00950   //iterate over every tupple, find distance, copy to symetric tupple
00951   for(int iy = 0; iy < NP_spaceSize; iy++)
00952   {
00953     NP_Dis[item][iy] = 0;
00954     FLOAT *npdis     = &NP_Dis[item][iy];
00955     // get distance between these two points
00956     for(int px = 0; px < NP_dimSize; px++)
00957     {
00958       *npdis = *npdis +
00959         pow((NP_Space->at(item)[px] - NP_Space->at(iy)[px]),2);
00960     }
00961     NP_Dis[iy][item] = *npdis;
00962   }
00963 
00964   // find distance as sqrt(sum(sqared distances))
00965   // take the inverse distance 1/D
00966   for(int iy = 0; iy < NP_spaceSize; iy++)
00967   {
00968     if(NP_Dis[item][iy] != 0)
00969     {
00970       NP_density[item] += 1/sqrt(NP_Dis[item][iy]);
00971       NP_density[iy]   += 1/sqrt(NP_Dis[item][iy]);
00972     }
00973   }
00974 }
00975 
00976 
00977 /************************************************************************/
00978 
00979 template <class FLOAT>
00980 void NPclassify2<FLOAT>::NPbiasConvolveSpace()
00981 {
00982   for(int ix = 0; ix < NP_spaceSize; ix++)
00983   {
00984     FLOAT distance = 0.0F;
00985     //iterate over every tupple, find distance, copy to symetric tupple
00986     for(int iy = 0; iy < NP_covHolderSize; iy++)
00987     {
00988       // get distance between these two points
00989       for(int px = 0; px < NP_dimSize; px++)
00990       {
00991         distance +=
00992           pow((NP_Space->at(ix)[px] - NP_covHolder->at(iy).mean[px]),2);
00993       }
00994 
00995       // find distance as sqrt(sum(sqared distances))
00996       // take the inverse distance 1/D
00997       if(distance != 0.0F)
00998         NP_density[ix] += (1/sqrt(distance))
00999           * NP_covHolder->at(iy).samples * NP_biasWeight;
01000     }
01001   }
01002 }
01003 
01004 /************************************************************************/
01005 
01006 template <class FLOAT>
01007 void NPclassify2<FLOAT>::NPbasicMeanDensity()
01008 {
01009   // find mean density
01010   FLOAT sumSquares = 0;
01011   typename std::vector<FLOAT>::iterator idensity = NP_density.begin();
01012   NP_sumDensity = 0;
01013   for(int ix = 0; ix < NP_spaceSize; ix++, ++idensity)
01014   {
01015     NP_sumDensity = *idensity + NP_sumDensity;
01016     sumSquares    += pow((*idensity),2)/(NP_spaceSize);
01017     if(*idensity > NP_maxDensity)
01018       NP_maxDensity = *idensity;
01019   }
01020   NP_meanDensity = NP_sumDensity/(NP_spaceSize);
01021   NP_stdDensity  = sqrt(sumSquares - pow(NP_meanDensity,2));
01022 }
01023 
01024 /************************************************************************/
01025 
01026 template <class FLOAT>
01027 void NPclassify2<FLOAT>::NPcomputeEntropy()
01028 {
01029   NP_totalEntropy = 0.0F;
01030   typename std::vector<FLOAT>::iterator idensity = NP_density.begin();
01031   typename std::vector<FLOAT>::iterator ientropy = NP_entropy.begin();
01032   if(NP_sumDensity != 0)
01033   {
01034     for(int ix = 0; ix < NP_spaceSize; ix++, ++idensity, ++ientropy)
01035     {
01036       *ientropy = (*idensity/NP_sumDensity)*log(*idensity/NP_sumDensity);
01037       NP_totalEntropy += (*ientropy);
01038     }
01039   }
01040   NP_totalEntropy = -1*NP_totalEntropy;
01041 }
01042 
01043 /************************************************************************/
01044 
01045 template <class FLOAT>
01046 void NPclassify2<FLOAT>::NPlinkSpace()
01047 {
01048   // link points together. Take the closest point that is higher in
01049   // density
01050   NPbasicMeanDensity();
01051   NPcomputeEntropy();
01052 
01053   FLOAT thresh = (NP_preDenWeight1*NP_meanDensity)
01054     + (NP_preDenWeight2*pow(NP_meanDensity,2));
01055   typename std::vector<FLOAT>::iterator idensity = NP_density.begin();
01056   std::vector<bool>::iterator ilowDensity        = NP_lowDensity.begin();
01057   for(int ix = 0; ix < NP_spaceSize; ix++, ++idensity, ++ilowDensity)
01058   {
01059     if(*idensity < thresh)
01060     {
01061       *ilowDensity = true;
01062       NP_lowDensCount++;
01063     }
01064     else
01065       *ilowDensity = false;
01066   }
01067   NP_newSampleSize = NP_spaceSize - NP_lowDensCount;
01068 
01069   /* link all nodes to the node which is closest but which has
01070      a higher density. Do this by comparing every node to every other
01071      node, This is O(n^2). Do not add any nodes to the tree which
01072      have a low density.
01073   */
01074 
01075   NPdoLinkSpace();
01076 }
01077 
01078 /************************************************************************/
01079 
01080 template <class FLOAT>
01081 void NPclassify2<FLOAT>::NPlinkSpaceIncr()
01082 {
01083   /*
01084   // link points together. Take the closest point that is higher in
01085   // density
01086   NPbasicMeanDensity();
01087   NP_lowDensCount = 0;
01088   //std::cout << "meanDensity " << meanDensity << "\n";
01089   //std::cout << "stdDensity " << stdDensity << "\n";
01090   FLOAT thresh = (NP_preDenWeight1*NP_meanDensity)
01091     + (NP_preDenWeight2*pow(NP_meanDensity,2));
01092   for(int ix = 0; ix < NP_spaceSize; ix++)
01093   {
01094     if(NP_density[ix] < thresh)
01095     {
01096       NP_lowDensity[ix] = true;
01097       NP_lowDensCount++;
01098     }
01099     else
01100       NP_lowDensity[ix] = false;
01101   }
01102   NP_newSampleSize = NP_spaceSize - NP_lowDensCount;
01103 
01104   //std::cerr << "new sample size " <<  NP_newSampleSize << "\n";
01105   int temp1 = -1;
01106   FLOAT temp2 = -1.0F;
01107   int *best = &temp1;
01108   FLOAT *bestVal = &temp2;
01109   // link all nodes to the node which is closest but which has
01110   // a higher density. Do this by comparing every node to every other
01111   // node, This is O(n^2). Do not add any nodes to the tree which
01112   // have a low density.
01113 
01114 
01115   // two things must happen here
01116   //  (a) my parent now has a lower density than me, so I must totally
01117   //       update my links for this node and find a new parent
01118   //  (b) my parent is still better, I must check all nodes
01119   //       that had a lower density than me before hand to see if they
01120   //       now have a high density and are closer than my parent
01121 
01122   // My parent has a lower density than me, relink the whole list
01123   for(int ix = 0; ix < NP_spaceSize; ix++)
01124   {
01125     // (A) Check My parent
01126     if(NP_density[ix] > NP_density[NP_parent[ix]])
01127     {
01128       // relink
01129       NPdoLinkSpace(ix);
01130       // shrink list
01131       NPeditLessDensityList(ix);
01132       break;
01133     }
01134     // (B) check most of the guys who have a lower density
01135     tempCount = NP_lessDensityCount[ix];
01136     NP_lessDensityCount[ix] = 0;
01137     std::vector<int*>::iterator NP_lessDensityIter;
01138     NP_lessDensityIter = NP_lessDensity.at(ix);
01139     for(int in = 0; in < tempCount; in++)
01140     {
01141       if(NP_density[in] > NP_density[ix])
01142       {
01143         if((NP_Dis[ix][in] < *bestVal) || (*bestVal == -1))
01144         {
01145           bestVal = &NP_Dis[ix][in];
01146           best = &NP_keyVal[in];
01147         }
01148       }
01149       else
01150       {
01151         if((NP_Dis[ix][in] < *bestVal) || (*bestVal == -1))
01152         {
01153           NP_lessDensityIter** = &NP_keyVal[in];
01154           ++NP_lessDensityIter; NP_lessDensityCount[ix]++;
01155         }
01156       }
01157     }
01158     if(*best != -1)
01159     {
01160       // A change has been found, I now have a new parent
01161       //std::cerr << "Set non-stem best " << *best << "\n";
01162       // RESET my parents list
01163       long newCount = 0;
01164       for(int cm = 0; cm < NP_children[NP_parent[ix]]; cm++)
01165       {
01166         if(NP_childMap[NP_parent[ix]][cm] != NP_keyVal[ix])
01167         {
01168           NP_childMap[NP_parent[ix]][newCount]
01169             = NP_childMap[NP_parent[ix]][cm];
01170           newCount++;
01171         }
01172       }
01173       NP_children[NP_parent[ix]] = &NP_keyVal[newCount];
01174 
01175       // JOIN my new parents list
01176       NP_parent[ix] = &NP_keyVal[*best];
01177       NP_distance[ix] = NP_Dis[ix][*best];
01178       // add myself to my parents list of children
01179       // remove me from my old parent
01180       NP_childMap[*best][NP_children[*best]] = &NP_keyVal[ix];
01181       NP_children[*best]++;
01182       //std::cerr << "LINKING "
01183       //          << "This " << NP_keyVal[ix] << " to " << *NP_parent[ix]
01184       //          << " Childmap [" << *best << "][" << NP_children[*best]
01185       //          << "] distance " << NP_distance[ix] << "\n";
01186     }
01187   }
01188   */
01189 }
01190 
01191 /************************************************************************/
01192 
01193 template <class FLOAT>
01194 void NPclassify2<FLOAT>::NPdoLinkSpace()
01195 {
01196   int temp1 = -1;
01197   FLOAT temp2 = -1.0F;
01198   int *best = &temp1;
01199   FLOAT *bestVal = &temp2;
01200   NP_stems = 0;
01201   /* link all nodes to the node which is closest but which has
01202      a higher density. Do this by comparing every node to every other
01203      node, This is O(n^2). Do not add any nodes to the tree which
01204      have a low density.
01205   */
01206   typename std::vector<FLOAT>::iterator  idensityX    = NP_density.begin();
01207   std::vector<bool>::iterator            ilowDensityX = NP_lowDensity.begin();
01208   typename std::vector<FLOAT>::iterator  idensityY;
01209   std::vector<bool>::iterator            ilowDensityY;
01210   typename std::vector<FLOAT>::iterator  iiDis;
01211   typename std::vector<FLOAT>::iterator  idistance    = NP_distance.begin();
01212   typename std::vector<std::vector<FLOAT> >::iterator iDis = NP_Dis.begin();
01213   std::vector<int>::iterator     ikeyValX     = NP_keyVal.begin();
01214   std::vector<int>::iterator     ikeyValY;
01215   std::vector<int*>::iterator    iparent      = NP_parent.begin();
01216   std::vector<int*>::iterator    irevStemVal  = NP_revStemVal.begin();
01217   std::vector<bool>::iterator    irevStem     = NP_revStem.begin();
01218   for(int ix = 0; ix < NP_spaceSize; ix++, ++idensityX,++ilowDensityX, ++iDis,
01219         ++iparent, ++idistance, ++irevStemVal, ++ikeyValX)
01220   {
01221     if(*ilowDensityX == false)
01222     {
01223       best         = &temp1;
01224       bestVal      = &temp2;
01225       idensityY    = NP_density.begin();
01226       ilowDensityY = NP_lowDensity.begin();
01227       iiDis        = iDis->begin();
01228       ikeyValY     = NP_keyVal.begin();
01229       for(int iy = 0; iy < ix; iy++, ++idensityY, ++ilowDensityY, ++iiDis,
01230             ++ikeyValY)
01231       {
01232         if(*ilowDensityY == false)
01233         {
01234           if(*idensityY > *idensityX)
01235           {
01236             if((*iiDis < *bestVal) || (*bestVal == -1))
01237             {
01238               bestVal = &*iiDis;
01239               best    = &*ikeyValY;
01240             }
01241           }
01242         }
01243       }
01244       int offset   = ix + 1;
01245       idensityY    = NP_density.begin() + offset;
01246       ilowDensityY = NP_lowDensity.begin() + offset;
01247       iiDis        = iDis->begin() + offset;
01248       ikeyValY     = NP_keyVal.begin() + offset;
01249       for(int iy = ix+1; iy < NP_spaceSize; iy++, ++idensityY, ++ilowDensityY,
01250             ++iiDis, ++ikeyValY)
01251       {
01252         if(*ilowDensityY == false)
01253         {
01254           if(*idensityY > *idensityX)
01255           {
01256             if((*iiDis < *bestVal) || (*bestVal == -1))
01257             {
01258               bestVal = &*iiDis;
01259               best    = &*ikeyValY;
01260             }
01261           }
01262         }
01263       }
01264 
01265       if(*best != -1)
01266       {
01267         *iparent   = &NP_keyVal[*best];
01268         *idistance = iDis->at(*best);
01269         // add myself to my parents list of children
01270         NP_childMap[*best][NP_children[*best]] = &*ikeyValX;
01271         NP_children[*best]++;
01272       }
01273       else
01274       {
01275         NP_stem[NP_stems] = &*ikeyValX;
01276         *irevStemVal      = &NP_keyVal[NP_stems];
01277         *iparent          = &*ikeyValX;
01278         *irevStem         = true;
01279         NP_stems++;
01280       }
01281     }
01282   }
01283 }
01284 
01285 /************************************************************************/
01286 /*
01287 template <class FLOAT>
01288 void NPclassify2<FLOAT>::NPdoLinkSpaceIter(int item)
01289 {
01290 
01291   int temp1 = -1;
01292   FLOAT temp2 = -1.0F;
01293   int *best = &temp1;
01294   FLOAT *bestVal = &temp2;
01295   NP_stems = 0;
01296      link all nodes to the node which is closest but which has
01297      a higher density. Do this by comparing every node to every other
01298      node, This is O(n^2). Do not add any nodes to the tree which
01299      have a low density.
01300 
01301   std::vector<std::vector<int*> >::iterator NP_lessDensityIter;
01302   std::vector<int*>::iterator NP_lessDensityIterIter;
01303   std::vector<int>::iterator NP_lessDensityCountIter;
01304 
01305   NP_lessDensityIter       = NP_lessDensity.at(item);
01306   NP_lessDensityCountIter  = NP_lessDensityCount.at(item);
01307   *NP_lessDensityCountIter = 0;
01308   NP_lessDensityIterIter   = NP_lessDensityIter->begin();
01309 
01310   for(int iy = 0; iy < item; iy++)
01311   {
01312     if(NP_density[iy] > NP_density[item])
01313     {
01314       if((NP_Dis[item][iy] < *bestVal) || (*bestVal == -1))
01315       {
01316         bestVal = &NP_Dis[item][iy];
01317         best = &NP_keyVal[iy];
01318       }
01319     }
01320     else
01321     {
01322       if(NP_Dis[item][iy] < *bestVal) || (*bestVal == -1))
01323       {
01324         **NP_lessDensityIterIter = &NP_keyVal[iy];
01325         ++NP_lessDensityIterIter; NP_lessDensityCountIter* += 1;
01326       }
01327     }
01328   }
01329   for(int iy = item+1; iy < NP_spaceSize; iy++)
01330   {
01331     if(NP_density[iy] > NP_density[item])
01332     {
01333       if((NP_Dis[item][iy] < *bestVal) || (*bestVal == -1))
01334       {
01335         bestVal = &NP_Dis[item][iy];
01336         best = &NP_keyVal[iy];
01337       }
01338     }
01339     else
01340     {
01341       if(NP_Dis[item][iy] < *bestVal) || (*bestVal == -1))
01342       {
01343         **NP_lessDensityIterIter = &NP_keyVal[iy];
01344         ++NP_lessDensityIterIter; NP_lessDensityCountIter* += 1;
01345       }
01346     }
01347   }
01348 
01349   if(*best != -1)
01350   {
01351     NP_parent[item] = &NP_keyVal[*best];
01352     NP_distance[item] = NP_Dis[item][*best];
01353     // add myself to my parents list of children
01354     NP_childMap[*best][NP_children[*best]] = &NP_keyVal[item];
01355     NP_children[*best]++;
01356   }
01357   else
01358   {
01359     //LINFO("STEM SET - as default");
01360     NP_stem[NP_stems] = &NP_keyVal[item];
01361     NP_revStemVal[item] = &NP_keyVal[NP_stems];
01362     NP_parent[item] = &NP_keyVal[item];
01363     NP_revStem[item] = true;
01364     NP_stems++;
01365   }
01366   //}
01367   //
01368 */
01369 
01370 
01371 /************************************************************************/
01372 
01373 template <class FLOAT>
01374 void NPclassify2<FLOAT>::NPmapSpace()
01375 {
01376   /* This will map all decendants to their parent nodes such that
01377      a list is built which contains each decentant for every node.
01378      that is, line 43 would have all decendants listed for node 43.
01379      this is done in n(log(n)) time by having a node place it's self
01380      in every predecessor(parent) above it. In essence by exploring
01381      the tree upwards (bottom up).
01382      Also: build a list of all my predecessors at the same time
01383   */
01384   std::vector<bool>::iterator ilowDensity = NP_lowDensity.begin();
01385   std::vector<int>::iterator  ikeyVal     = NP_keyVal.begin();
01386   std::vector<int>::iterator  ipredCount  = NP_predCount.begin();
01387   std::vector<std::vector<int*> >::iterator ipred = NP_pred.begin();
01388 
01389   for(unsigned int ix = 0; ix < NP_uspaceSize; ix++, ++ilowDensity,
01390         ++ikeyVal,++ipredCount, ++ipred)
01391   {
01392     if(*ilowDensity == false)
01393     {
01394       bool stop = false;
01395       int *currentParent = NP_parent[ix];
01396       while(stop == false)
01397       {
01398         for(int sc = 0; sc < NP_stems; sc++)
01399         {
01400           if(currentParent == NP_stem[sc])
01401           {
01402             stop = true;
01403             break;
01404           }
01405         }
01406         // who am I a decendant to, add me to their list
01407         NP_decend[*currentParent]
01408           [NP_decCount[*currentParent]] = &*ikeyVal;
01409         NP_decCount[*currentParent]++;
01410         // who are my predicessors, add them to my list
01411         ipred->at(*ipredCount) = &NP_keyVal[*currentParent];
01412         *ipredCount            = *ipredCount + 1;
01413         currentParent          = NP_parent[*currentParent];
01414       }
01415     }
01416   }
01417 }
01418 
01419 /************************************************************************/
01420 template <class FLOAT>
01421 void NPclassify2<FLOAT>::NPanalizeSpace()
01422 {
01423   FLOAT sumD = 0; double sumSquaresD = 0;
01424   FLOAT sumC = 0; double sumSquaresC = 0;
01425   FLOAT sumO = 0; double sumSquaresO = 0;
01426   typename std::vector<FLOAT>::iterator idistance   = NP_distance.begin();
01427   std::vector<int>::iterator    ichildren           = NP_children.begin();
01428   std::vector<int>::iterator    idecCount           = NP_decCount.begin();
01429   std::vector<bool>::iterator   ilowDensity         = NP_lowDensity.begin();
01430   // find mean distance between linked nodes
01431 
01432   for(unsigned int ix = 0; ix < NP_uspaceSize; ix++, ++idistance, ++ichildren,
01433         ++idecCount, ++ilowDensity)
01434   {
01435     if(*ilowDensity == false)
01436     {
01437       // find the mean distances of links
01438       sumD        += *idistance;
01439       sumSquaresD += pow((*idistance),2)/NP_newSampleSize;
01440 
01441       // find the mean number of children
01442       sumC        += *ichildren;
01443       sumSquaresC += pow(((FLOAT)*ichildren),2)/NP_newSampleSize;
01444 
01445       // find mean number of decendants
01446       sumO        += *idecCount;  // previously childMapTot, childMap*
01447       sumSquaresO += pow(((FLOAT)*idecCount),2)/NP_newSampleSize;
01448     }
01449   }
01450   if(NP_newSampleSize == 0)
01451     NP_newSampleSize = 1;
01452 
01453   NP_meanDistance = sumD/NP_newSampleSize;
01454   NP_stdDistance  = sqrt(sumSquaresD - pow(NP_meanDistance,2));
01455 
01456   NP_meanChild    = sumC/NP_newSampleSize;
01457   NP_stdChildren  = sqrt(sumSquaresC - pow(NP_meanChild,2));
01458 
01459   NP_meanDecCount = sumO/NP_newSampleSize;
01460   NP_stdDecCount  = sqrt(sumSquaresO - pow(NP_meanDecCount,2));
01461 
01462 }
01463 
01464 /************************************************************************/
01465 
01466 template <class FLOAT>
01467 void NPclassify2<FLOAT>::NPevolveSpace()
01468 {
01469 
01470   //initial threshold is a function of standard deviation and a weight
01471   //and number of children and a weight for that
01472   std::vector<bool>::iterator   ilowDensity = NP_lowDensity.begin();
01473   std::vector<bool>::iterator   irevStem    = NP_revStem.begin();
01474   std::vector<int>::iterator    ikeyVal     = NP_keyVal.begin();
01475   std::vector<int>::iterator    idecCount   = NP_decCount.begin();
01476   std::vector<int*>::iterator   irevStemVal = NP_revStemVal.begin();
01477   typename std::vector<FLOAT>::iterator idistance   = NP_distance.begin();
01478   typename std::vector<FLOAT>::iterator idensity    = NP_density.begin();
01479 
01480 
01481   // use polynomial optimized (linear regression) thresholds
01482   FLOAT threshDensity = (NP_polyDensObjectCut1*NP_meanDensity+
01483                NP_polyDensObjectCut2*pow(NP_meanDensity,(FLOAT)2.0)+
01484                NP_polyDensObjectCut3*pow(NP_meanDensity,(FLOAT)3.0)) /
01485     (NP_stdDensity+1);
01486 
01487   FLOAT threshDecend = (((NP_entCWeight1*NP_totalEntropy)+NP_CWeight1)
01488                          *NP_meanDecCount) -
01489     (((NP_entCWeight2*NP_totalEntropy)+NP_CWeight2)
01490      *pow(NP_meanDecCount,2));
01491 
01492   FLOAT threshDensity2 = (((NP_entDenWeight1*NP_totalEntropy)+NP_DenWeight1)
01493                            *NP_stdDensity)
01494     + (((NP_entDenWeight2*NP_totalEntropy)+NP_DenWeight2)
01495        *pow(NP_stdDensity,2));
01496 
01497   FLOAT threshDistance = (((NP_entDWeight1*NP_totalEntropy)+NP_DWeight1)
01498                            *NP_stdDistance)
01499     + (((NP_entDWeight2*NP_totalEntropy)+NP_DWeight2)
01500        *pow(NP_stdDistance,2));
01501 
01502 
01503   for(unsigned int ix = 0; ix < NP_uspaceSize; ix++, ++ilowDensity, ++irevStem,
01504         ++ikeyVal, ++idecCount, ++irevStemVal, ++idistance, ++idensity)
01505   {
01506     if(*ilowDensity == false)
01507     {
01508       FLOAT measureDistance = *idistance      - NP_meanDistance;
01509       FLOAT measureDensity  = *idensity       - NP_meanDensity;
01510       FLOAT measureDensity2 = NP_meanDensity  - *idensity;
01511 
01512       if((measureDensity < 0) && (measureDensity < threshDensity2))
01513         *ilowDensity = true;
01514 
01515       // How many std are you from the mean link distance. Use a weight that
01516       // signifies how far off you can be
01517       // look at both intre and inter class variance
01518 
01519       if((((measureDistance > threshDistance) ||
01520            (measureDensity2 > threshDensity))
01521           &&
01522           (*idecCount > threshDecend)) ||
01523          (*idistance > ( NP_hardLinkSize
01524                          + ( NP_enthardLinkSize*NP_totalEntropy ))))
01525       {
01526         if(*ilowDensity == false)
01527         {
01528           if(*irevStem == false)
01529           {
01530             // how many grandchildren do you have compaired with the mean
01531             // make sure you have lots. Remove outliers
01532             NP_stem[NP_stems] = &*ikeyVal;
01533             *irevStemVal      = &NP_keyVal[NP_stems];
01534             NP_stems++;
01535             *irevStem         = true;
01536           }
01537         }
01538       }
01539     }
01540   }
01541   //std::cout << "FIRST ROUND STEMS: " << NP_stems << "\n";
01542   NPcomputeMasters();
01543 }
01544 
01545 /************************************************************************/
01546 
01547 template <class FLOAT>
01548 void NPclassify2<FLOAT>::NPanalizeInterSpace()
01549 {
01550   // find masters, the class clusters
01551   // compute interclass variance and mean
01552   for(int i = 0; i < NP_stems; i++)
01553   {
01554     NP_meanInterDistance[i] = 0;
01555     NP_stdInterDistance[i]  = 0;
01556     NP_meanInterChild[i]    = 0;
01557     NP_stdInterChild[i]     = 0;
01558     NP_interEntropy[i]      = 0;
01559 
01560     if(NP_classSize[i] == 0)
01561       NP_classSize[i] = 1;
01562   }
01563 
01564 
01565   // find mean for interclass statistics
01566   for(unsigned int ix = 0; ix < NP_uspaceSize; ix++)
01567   {
01568     //int *index = NP_classIndex[*NP_master[ix]];
01569     int *index = NP_classIndex[ix];
01570     // count how many decendants I have inside my class
01571     for(int d = 0; d < NP_decCount[ix]; d++)
01572     {
01573       if(NP_master[ix] == NP_master[*NP_decend[ix][d]])
01574       {
01575         NP_subDecCount[ix]++;
01576       }
01577     }
01578 
01579     if((NP_revStem[ix] == false) && (NP_lowDensity[ix] == false))
01580     {
01581       NP_meanInterDistance[*index] += NP_distance[ix];
01582       NP_meanInterDensity[*index]  += NP_density[ix];
01583       NP_meanInterChild[*index]    += NP_subDecCount[ix];
01584     }
01585   }
01586 
01587   for(int i = 0; i < NP_stems; i++)
01588   {
01589     // copy over before computing full mean
01590     NP_sumInterDensity[i]   = NP_meanInterDensity[i];
01591     NP_meanInterDistance[i] = NP_meanInterDistance[i]/NP_classSize[i];
01592     NP_meanInterDensity[i]  = NP_meanInterDensity[i] /NP_classSize[i];
01593     NP_meanInterChild[i]    = NP_meanInterChild[i]   /NP_classSize[i];
01594   }
01595 
01596   // compute entropy per inter class
01597   for(unsigned int ix = 0; ix < NP_uspaceSize; ix++)
01598   {
01599     int *index = NP_classIndex[ix];
01600 
01601     if((NP_revStem[ix] == false) && (NP_lowDensity[ix] == false))
01602     {
01603       NP_interEntropy[*index] +=
01604         (NP_density[ix]/NP_sumInterDensity[*index])
01605         *log(NP_density[ix]/NP_sumInterDensity[*index]);
01606     }
01607   }
01608 
01609   for(unsigned int ix = 0; ix < NP_uspaceSize; ix++)
01610   {
01611     //int *index = NP_classIndex[*NP_master[ix]];
01612     int *index = NP_classIndex[ix];
01613     if((NP_revStem[ix] == false) && (NP_lowDensity[ix] == false))
01614     {
01615       NP_stdInterDistance[*index]
01616         += pow((NP_meanInterDistance[*index] - NP_distance[ix]),2);
01617       NP_stdInterDensity[*index]
01618         += pow((NP_meanInterDensity[*index]  - NP_density[ix]),2);
01619       NP_stdInterChild[*index]
01620         += pow((NP_meanInterChild[*index]    - NP_subDecCount[ix]),2);
01621     }
01622   }
01623 
01624   for(int i = 0; i < NP_stems; i++)
01625   {
01626     NP_stdInterDistance[i] = sqrt(NP_stdInterDistance[i]/NP_classSize[i]);
01627     NP_stdInterDensity[i]  = sqrt(NP_stdInterDensity[i] /NP_classSize[i]);
01628     NP_stdInterChild[i]    = sqrt(NP_stdInterChild[i]   /NP_classSize[i]);
01629     NP_interEntropy[i]     = -1.0F*NP_interEntropy[i];
01630   }
01631 }
01632 
01633 /************************************************************************/
01634 
01635 template <class FLOAT>
01636 void NPclassify2<FLOAT>::NPevolveInterSpace()
01637 {
01638   //initial threshold is a function of standard deviation and a weight
01639   //and number of children and a weight for that
01640 
01641   for(unsigned int ix = 0; ix < NP_uspaceSize; ix++)
01642   {
01643     int *index = NP_classIndex[*NP_master[ix]];
01644     if(NP_revStem[ix] == false)
01645     {
01646       FLOAT threshDistance = (((NP_entIDWeight1*NP_interEntropy[*index])
01647                                +NP_IDWeight1)
01648                               *NP_stdInterDistance[*index])
01649         + (((NP_entIDWeight2*NP_interEntropy[*index])
01650             + NP_IDWeight2)
01651            *pow(NP_stdInterDistance[*index],2))
01652         *((NP_stdInterDensity[*index]+1)*.2);
01653 
01654       // How many std are you from the mean link distance. Use a weight that
01655       // signifies how far off you can be
01656       // look at both intre and inter class variance
01657       FLOAT measureDistance = NP_distance[ix] -
01658         NP_meanInterDistance[*index];
01659 
01660       if((measureDistance > threshDistance)
01661          &&
01662          (NP_subDecCount[ix] > ((NP_enthardClassSize*NP_interEntropy[*index])
01663           +NP_hardClassSize))
01664          &&
01665          (NP_subDecCount[ix]  >
01666           (((NP_entICWeight1*NP_interEntropy[*index]) +
01667            NP_ICWeight1)*NP_meanInterDensity[*index])))
01668       {
01669         // check to make sure I'm not already a stem
01670         // how many grandchildren do you have compaired with the mean
01671         // make sure you have lots. Remove outliers
01672         NP_stem[NP_stems] = &NP_keyVal[ix];
01673         NP_revStemVal[ix] = &NP_keyVal[NP_stems];
01674         NP_stems++;
01675         NP_revStem[ix]    = true;
01676       }
01677     }
01678   }
01679   NPcomputeMasters();
01680 }
01681 
01682 /************************************************************************/
01683 
01684 template <class FLOAT>
01685 void NPclassify2<FLOAT>::NPanalizeClassDensity()
01686 {
01687   typename std::vector<FLOAT>::iterator imeanClassDensity
01688     = NP_meanClassDensity.begin();
01689   typename std::vector<FLOAT>::iterator istdClassDensity
01690     = NP_stdClassDensity.begin();
01691   typename std::vector<FLOAT>::iterator idensity = NP_density.begin();
01692   std::vector<bool>::iterator irevStem           = NP_revStem.begin();
01693   std::vector<bool>::iterator ilowDensity        = NP_lowDensity.begin();
01694   std::vector<int>::iterator iclassSize          = NP_classSize.begin();
01695   std::vector<int*>::iterator imaster            = NP_master.begin();
01696 
01697   // find masters, the class clusters
01698   // compute interclass variance and mean
01699   for(int i = 0; i < NP_stems; i++, ++imeanClassDensity,
01700         ++istdClassDensity)
01701   {
01702     *imeanClassDensity = 0.0F;
01703     *istdClassDensity  = 0.0F;
01704   }
01705 
01706   // find mean for interclass statistics
01707   for(unsigned int ix = 0; ix < NP_uspaceSize; ix++, ++irevStem, ++ilowDensity,
01708         ++idensity, ++imaster)
01709   {
01710     int *index = NP_classIndex[ix];
01711     if((*irevStem == false) && (*ilowDensity == false))
01712     {
01713       NP_meanClassDensity[*index] += *idensity;
01714     }
01715   }
01716   imeanClassDensity = NP_meanClassDensity.begin();
01717 
01718   for(int i = 0; i < NP_stems; i++, ++imeanClassDensity, ++iclassSize)
01719   {
01720     if(*iclassSize != 0)
01721     {
01722       *imeanClassDensity = *imeanClassDensity/(*iclassSize);
01723     }
01724     else
01725     {
01726       *imeanClassDensity = 0;
01727     }
01728   }
01729 
01730   irevStem          = NP_revStem.begin();
01731   ilowDensity       = NP_lowDensity.begin();
01732   idensity          = NP_density.begin();
01733   imeanClassDensity = NP_meanClassDensity.begin();
01734   imaster           = NP_master.begin();
01735 
01736   for(unsigned int ix = 0; ix < NP_uspaceSize; ix++, ++irevStem, ++ilowDensity,
01737         ++imeanClassDensity, ++idensity, ++imaster)
01738   {
01739     int *index = NP_classIndex[ix];
01740     if((*irevStem == false) && (*ilowDensity == false))
01741     {
01742       NP_stdClassDensity[*index]
01743         += pow((NP_meanClassDensity[*index] - *idensity),2);
01744     }
01745   }
01746 
01747   istdClassDensity = NP_stdClassDensity.begin();
01748   iclassSize = NP_classSize.begin();
01749 
01750   for(int i = 0; i < NP_stems; i++, ++iclassSize, ++istdClassDensity)
01751   {
01752     if(*iclassSize != 0)
01753     {
01754       *istdClassDensity = sqrt(*istdClassDensity/(*iclassSize));
01755     }
01756     else
01757     {
01758       *istdClassDensity = 0;
01759     }
01760   }
01761 }
01762 
01763 /************************************************************************/
01764 
01765 template <class FLOAT>
01766 void NPclassify2<FLOAT>::NPcomputeMasters()
01767 {
01768   // find my masters, form discrete classes
01769   /* This is done by taking the first predecesor that is a stem
01770      and treating it as my master. I then add myself to its list
01771      of nodes (NP_masterIndex) of slaves
01772   */
01773 
01774   for(int st = 0; st < NP_stems; st++)
01775   {
01776     NP_classSize[st]                  = 0;
01777     NP_masterIndexCount[*NP_stem[st]] = 0;
01778   }
01779 
01780   for(unsigned int ix = 0; ix < NP_uspaceSize; ix++)
01781   {
01782     bool stop = false;
01783     bool finish = false;
01784 
01785     for(int pr = 0; pr < NP_predCount[ix]; pr++)
01786     {
01787       for(int st = 0; st < NP_stems; st++)
01788       {
01789         // check to see if I am a stem/master
01790         if(NP_revStem[ix] && (finish == false))
01791         {
01792           if(st == *NP_revStemVal[ix])
01793           {
01794             // I am in my own master node class
01795             NP_Class[st][NP_classSize[st]] = &NP_keyVal[ix];
01796             // Increment class size
01797             NP_classSize[st]++;
01798             // index from me to my class
01799             NP_classIndex[ix]              = &NP_keyVal[st];
01800             finish                         = true;
01801           }
01802         }
01803         // climb up the ladder of predecessor to find the closest master
01804         if(NP_stem[st] == NP_pred[ix][pr])
01805         {
01806           // which node is my master
01807           NP_master[ix] = NP_stem[st];
01808           if(NP_revStem[ix] == false)
01809           {
01810             // what class am I in, store this for output only
01811             // (never used again)
01812             NP_Class[st][NP_classSize[st]] = &NP_keyVal[ix];
01813             // Increment class size
01814             NP_classSize[st]++;
01815             // index from me to my class
01816             NP_classIndex[ix] = &NP_keyVal[st];
01817           }
01818           // index from my masters list to me
01819           NP_masterIndex[*NP_stem[st]][NP_masterIndexCount[*NP_stem[st]]]
01820             = &NP_keyVal[ix];
01821           // increment my masters list counter
01822           NP_masterIndexCount[*NP_stem[st]]++;
01823           stop = true;
01824           break;
01825         }
01826       }
01827       if(stop == true)
01828         break;
01829     }
01830   }
01831 }
01832 
01833 /************************************************************************/
01834 
01835 template <class FLOAT>
01836 void NPclassify2<FLOAT>::NPparamSpace(int samples, int dim)
01837 {
01838   NP_spaceSize  = samples;
01839   NP_uspaceSize = (unsigned)samples;
01840   NP_dimSize    = dim;
01841   NP_udimSize   = (unsigned)dim;
01842 }
01843 
01844 /************************************************************************/
01845 
01846 template <class FLOAT>
01847 void NPclassify2<FLOAT>::NPreverseMap()
01848 {
01849   typename std::vector<FLOAT*> tempVec(NP_spaceSize,&NP_fZERO);
01850   NP_reverseDisMap.resize(NP_spaceSize,tempVec);
01851 
01852   for(unsigned int x = 0; x < NP_Dis.size(); x++)
01853   {
01854     for(unsigned int y = 0; y < NP_Dis.size(); y++)
01855     {
01856       NP_reverseDisMap[x][y] = &NP_Dis[y][x];
01857 
01858     }
01859   }
01860 }
01861 
01862 /************************************************************************/
01863 
01864 template <class FLOAT>
01865 void NPclassify2<FLOAT>::NPresizeSpace(int samples, int dim)
01866 {
01867   // resize vectors to default size initially
01868   // we suck memory because we care!!
01869   NP_fZERO = 0;
01870   NPparamSpace(samples,dim);
01871 
01872   typename std::vector<FLOAT> tempf(NP_spaceSize,0.0F);
01873   // The distance between any two nodes in space
01874   NP_Dis.resize(NP_spaceSize,tempf);
01875   // create reverse mapping for NP_Dis
01876   NPreverseMap();
01877   // holds the measure from metaclassify for a train
01878   NP_trainMeasure.resize(NP_spaceSize,0.0F);
01879   // Holds the distance from a node to its parent node
01880   NP_distance.resize(NP_spaceSize,0.0F);
01881   // the density of this node
01882   NP_density.resize(NP_spaceSize,0.0F);
01883   // entropy measure holder
01884   NP_entropy.resize(NP_spaceSize,0.0F);
01885   // this is the mean distance within a class
01886   NP_meanInterDistance.resize(NP_spaceSize,0.0F);
01887   // The standard deviation for meanInterDistance
01888   NP_stdInterDistance.resize(NP_spaceSize,0.0F);
01889   // this is the mean distance within a class
01890   NP_meanClassDensity.resize(NP_spaceSize,0.0F);
01891   // this is the sum density within a class used for entropy comp.
01892   NP_sumInterDensity.resize(NP_spaceSize,0.0F);
01893   // The standard deviation for meanInterDistance
01894   NP_stdClassDensity.resize(NP_spaceSize,0.0F);
01895   // Mean number of decendants per node inter class
01896   NP_meanInterChild.resize(NP_spaceSize,0.0F);
01897   // the standard deviation for meanInterClass
01898   NP_stdInterChild.resize(NP_spaceSize,0.0F);
01899   // Mean density for nodes inter class
01900   NP_meanInterDensity.resize(NP_spaceSize,0.0F);
01901   // Standard deviation for meanInterDensity
01902   NP_stdInterDensity.resize(NP_spaceSize,0.0F);
01903   // Entropy measure for intercalss
01904   NP_interEntropy.resize(NP_spaceSize,0.0F);
01905 
01906   NP_ZERO = 0;
01907   std::vector<int*> temp(NP_spaceSize,&NP_ZERO);
01908   // Holds class membership for nodes
01909   NP_Class.resize(NP_spaceSize,temp);
01910   // Holds a list of all children for a node
01911   NP_childMap.resize(NP_spaceSize,temp);
01912   // Holds a list of all of nodes decendants
01913   NP_decend.resize(NP_spaceSize,temp);
01914   // Holds a list of all my predecessors
01915   NP_pred.resize(NP_spaceSize,temp);
01916   // List of all nodes I am master of
01917   NP_masterIndex.resize(NP_spaceSize,temp);
01918 
01919 
01920   // holds the ID of each stem for each class
01921   NP_stem.resize(NP_spaceSize,&NP_ZERO);
01922   // holds parent for a sample in cluster space
01923   NP_parent.resize(NP_spaceSize,&NP_ZERO);
01924   // lists who a nodes master is
01925   NP_master.resize(NP_spaceSize,&NP_ZERO);
01926   // lists who a nodes master is
01927   NP_classIndex.resize(NP_spaceSize,&NP_ZERO);
01928   // reverse index to the stem for which I am a master
01929   NP_revStemVal.resize(NP_spaceSize,&NP_ZERO);
01930 
01931 
01932   // Returns the number of samples in each class
01933   NP_classSize.resize(NP_spaceSize,0);
01934   // Holds the total number of decendants for a node
01935   NP_decCount.resize(NP_spaceSize,0);
01936   // Tells which links would have been ideal in the meta-classifier
01937   NP_idealLinks.resize(NP_spaceSize,0);
01938   // number of children for a given node
01939   NP_children.resize(NP_spaceSize,0);
01940   // tells how many predecessors I have
01941   NP_predCount.resize(NP_spaceSize,0);
01942   // counts how many nodes I am master of
01943   NP_masterIndexCount.resize(NP_spaceSize,0);
01944   //! Holds the total number of decendants for a node in this class
01945   NP_subDecCount.resize(NP_spaceSize,0);
01946 
01947 
01948   // Returns if the sample has a low density in the map
01949   NP_lowDensity.resize(NP_spaceSize,false);
01950   // tells if this node has a stem attached to it
01951   NP_revStem.resize(NP_spaceSize,false);
01952   // Tells if this node has been selected or not
01953   NP_selected.resize(NP_spaceSize,false);
01954 
01955   // lists the key number for any given node
01956   NP_keyVal.resize(NP_spaceSize,0);
01957   for(int k = 0; k < NP_spaceSize; k++)
01958   {
01959     NP_keyVal[k] = k;
01960   }
01961 
01962 
01963 }
01964 
01965 /************************************************************************/
01966 
01967 template <class FLOAT> inline
01968 FLOAT NPclassify2<FLOAT>::NPgaussKernel(FLOAT x, FLOAT mu, FLOAT sig) const
01969 {
01970   return (FLOAT)((1/sqrt(2*3.14159F*pow(sig,2.0F))) *
01971          (pow(2.71828F,-1*pow(x - mu,2.0F)/(2 * pow(sig,2.0F)))));
01972 }
01973 
01974 /************************************************************************/
01975 
01976 template <class FLOAT> inline
01977 FLOAT NPclassify2<FLOAT>::NPgaussKernel(FLOAT z) const
01978 {
01979   return (1/sqrt(2 * 3.14159F))*(pow(2.71828F,-1*(pow(z,2.0F)/2)));
01980 }
01981 
01982 /************************************************************************/
01983 template <class FLOAT> inline
01984 FLOAT NPclassify2<FLOAT>::NPsigmoidKernel(FLOAT beta, FLOAT v) const
01985 {
01986   return (1.0f / (1.0f + pow(2.71828f, (-2.0f * (beta * v)))));
01987 }
01988 
01989 template class NPclassify2<float>;
01990 
01991 // ######################################################################
01992 /* So things look consistent in everyone's emacs... */
01993 /* Local Variables: */
01994 /* indent-tabs-mode: nil */
01995 /* End: */
Generated on Sun May 8 08:07:03 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3