NPclassify.C

Go to the documentation of this file.
00001 /*!@file VFAT/NPclassify.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/NPclassify.C $
00036 // $Id: NPclassify.C 6003 2005-11-29 17:22:45Z rjpeters $
00037 //
00038 
00039 /* This is a non-parametric unsupervised  classifier for use in the
00040    future with kubists. It takes as an input data points in n dimentions.
00041    classification is done in a clustering meathod by finding for any point
00042    whats its local density is then linking that point to the next closest
00043    point that has a higher density rating. Class boundry is created by
00044    "snipping" links that are for instance too long. This meathod has the
00045    advantage of being non-parametric. It makes no assumptions about data
00046    distribution (per se) or how many classes may exist. By taking the
00047    nearest point of highest density it can also distinguish between two
00048    incidentally connected classes e.g. two classes that are clustered close
00049    together.
00050    Complexity is D*n^2
00051 */
00052 
00053 #include "VFAT/NPclassify.H"
00054 
00055 #include "Util/Assert.H"
00056 #include "Util/Timer.H"
00057 #include "Util/log.H"
00058 #include <fstream>
00059 #include <iostream>
00060 #include <math.h>
00061 
00062 // *****************************************
00063 // PUBLIC METHODS
00064 // *****************************************
00065 
00066 NPclassify::NPclassify(readConfig &settings, readConfig &polySet,
00067                        bool commandLineSettings)
00068 {
00069   // set up variables from config file
00070   CLS = commandLineSettings;
00071   defaultSize = (int)settings.getItemValueF("defaultSize");
00072   Con1 = settings.getItemValueF("Con1");
00073   Con2 = settings.getItemValueF("Con2");
00074   Con3 = settings.getItemValueF("Con3");
00075   hardClassSize = (long)settings.getItemValueF("hardClassSize");
00076   hardLinkSize = (long)settings.getItemValueF("hardLinkSize");
00077   DWeight1 = settings.getItemValueF("DWeight1");
00078   DWeight2 = settings.getItemValueF("DWeight2");
00079   CWeight1 = settings.getItemValueF("CWeight1");
00080   CWeight2 = settings.getItemValueF("CWeight2");
00081   IDWeight1 = settings.getItemValueF("IDWeight1");
00082   IDWeight2 = settings.getItemValueF("IDWeight2");
00083   ICWeight1 = settings.getItemValueF("ICWeight1");
00084   ICWeight2 = settings.getItemValueF("ICWeight2");
00085   DenWeight1 = settings.getItemValueF("DenWeight1");
00086   DenWeight2 = settings.getItemValueF("DenWeight2");
00087   preDenWeight1 = settings.getItemValueF("preDenWeight1");
00088   preDenWeight2 = settings.getItemValueF("preDenWeight2");
00089   trainChildWeight = settings.getItemValueF("trainChildWeight");
00090   doLinkMap = (int)settings.getItemValueF("doLinkMap");
00091   doDensityMap = (int)settings.getItemValueF("doDensityMap");
00092   doClassMap = (int)settings.getItemValueF("doClassMap");
00093   usePolySet = (int)settings.getItemValueF("usePolySet");
00094 
00095   polyDensObjectCut1 = polySet.getItemValueF("polyDensObjectCut1");
00096   polyDensObjectCut2 = polySet.getItemValueF("polyDensObjectCut2");
00097   polyDensObjectCut3 = polySet.getItemValueF("polyDensObjectCut3");
00098   polySpaceChildCut1 = polySet.getItemValueF("polySpaceChildCut1");
00099   polySpaceChildCut2 = polySet.getItemValueF("polySpaceChildCut2");
00100   polySpaceChildCut3 = polySet.getItemValueF("polySpaceChildCut3");
00101   // zero some initial counters
00102   resetSpace();
00103   // set up vectors to a reasonable initial size
00104   resizeSpace();
00105 }
00106 
00107 NPclassify::~NPclassify()
00108 {}
00109 
00110 void NPclassify::inputCommandLineSettings(double _distance, double _children,
00111                                double Idistance, double Ichildren,
00112                                long _hardClassSize, long _hardLinkSize,
00113                                double _polyDensObjectCut1,
00114                                double _polyDensObjectCut2,
00115                                double _polyDensObjectCut3)
00116 {
00117   DWeight1 = _distance;
00118   CWeight1 = _children;
00119   IDWeight1 = Idistance;
00120   ICWeight1 = Ichildren;
00121   hardClassSize = _hardClassSize;
00122   hardLinkSize = _hardLinkSize;
00123   polyDensObjectCut1 = _polyDensObjectCut1;
00124   polyDensObjectCut2 = _polyDensObjectCut2;
00125   polyDensObjectCut3 = _polyDensObjectCut3;
00126 }
00127 
00128 void NPclassify::addPoint(std::vector<long> point)
00129 {
00130   //FOO
00131 }
00132 
00133 void NPclassify::addSpace(std::vector<std::vector<double> > &space,long sSize)
00134 {
00135   // make sure space stays
00136   if(sSize == 0)
00137     sSize = space.size();
00138   long oldSpaceSize = spaceSize;
00139   spaceSize += sSize;
00140   if((unsigned)(spaceSize) >= Space.size())
00141     resizeSpace();
00142   for(int i = 0; i < sSize; i++)
00143   {
00144     Space[i+oldSpaceSize] = space[i];
00145   }
00146   //std::cerr << "SPACE SIZE " << spaceSize << "\n";
00147 }
00148 
00149 void NPclassify::echoSpace()
00150 {
00151   for(int i = 0; i < spaceSize; i++)
00152   {
00153     std::cerr << i << " ";
00154     for(unsigned int j = 0; j < Space[i].size(); j++)
00155       std::cerr << Space[i][j] << " ";
00156     std::cerr << "\n";
00157   }
00158 }
00159 
00160 void NPclassify::resetSpace()
00161 {
00162   //std::cerr << "SPACE RESET\n";
00163   spaceSize = 0;
00164   stems = 0;
00165   roots = 0;
00166 }
00167 
00168 void NPclassify::classifySpaceNew()
00169 {
00170   Timer tim;
00171   tim.reset();
00172   //int t1,t2;
00173   //int t0 = tim.get();  // to measure display time
00174   //std::cout << "CONVOLVE SPACE\n";
00175   convolveSpace2();
00176   //t1 = tim.get();
00177   //t2 = t1 - t0;
00178   //std::cout << "\tTIME: " << t2 << "ms\n";
00179   //std::cout << "LINK SPACE\n";
00180   linkSpace();
00181   //t1 = tim.get();
00182   //t2 = t1 - t0;
00183   //std::cout << "\tTIME: "<< t2 << "ms\n";
00184   //std::cout << "MAP SPACE\n";
00185   mapSpace();
00186   //t1 = tim.get();
00187   //t2 = t1 - t0;
00188   //std::cout << "\tTIME: "<< t2 << "ms\n";
00189   //std::cout << "ANALYZE SPACE\n";
00190   analizeSpace();
00191   //t1 = tim.get();
00192   //t2 = t1 - t0;
00193   //std::cout << "\tTIME: "<< t2 << "ms\n";
00194   //std::cout << "EVOLVE SPACE\n";
00195   evolveSpace();
00196   //t1 = tim.get();
00197   //t2 = t1 - t0;
00198   //std::cout << "\tTIME: "<< t2 << "ms\n";
00199   //std::cout << "ANALYZE INTER SPACE\n";
00200   analizeInterSpace();
00201   //t1 = tim.get();
00202   //t2 = t1 - t0;
00203   //std::cout << "\tTIME: "<< t2 << "ms\n";
00204   //std::cout << "EVOLVE INTER SPACE\n";
00205   evolveInterSpace();
00206   //t1 = tim.get();
00207   //t2 = t1 - t0;
00208   //std::cout << "\tTIME: "<< t2 << "ms\n";
00209 }
00210 
00211 void NPclassify::classifySpacePartial()
00212 {}
00213 
00214 long NPclassify::getStemNumber()
00215 {
00216   return stems;
00217 }
00218 
00219 double NPclassify::getMaxDensity()
00220 {
00221   return maxDensity;
00222 }
00223 
00224 bool NPclassify::isLowDensity(long item)
00225 {
00226   return lowDensity[item];
00227 }
00228 
00229 bool NPclassify::isStem(long item)
00230 {
00231   return revStem[item];
00232 }
00233 
00234 std::vector<double> NPclassify::getDensity()
00235 {
00236   return density;
00237 }
00238 
00239 std::vector<long> NPclassify::getStems()
00240 {
00241   return stem;
00242 }
00243 
00244 long NPclassify::getClassSize(long _Class)
00245 {
00246   ASSERT((_Class <= (signed)classSize.size()) && (_Class >= 0));
00247   return classSize[_Class];
00248 }
00249 
00250 long NPclassify::getMinClassSize()
00251 {
00252   return hardClassSize;
00253 }
00254 
00255 std::vector<long> NPclassify::getClass(long _Class)
00256 {
00257   ASSERT((_Class <= (signed)Class.size()) && ((_Class >= 0)));
00258   return Class[_Class];
00259 }
00260 
00261 long NPclassify::getClass(long _Class, long item)
00262 {
00263   ASSERT((_Class <= (signed)Class.size()) && ((_Class >= 0)));
00264   ASSERT((item <= (signed)Class[item].size()) && ((item >= 0)));
00265   return Class[_Class][item];
00266 }
00267 
00268 double NPclassify::getFeature(long m_feature_index, long n_vector_index)
00269 {
00270   ASSERT((m_feature_index <= (signed)Space.size()) && (m_feature_index >= 0));
00271   ASSERT((n_vector_index <= (signed)Space[m_feature_index].size())
00272          && (n_vector_index >= 0));
00273   return Space[m_feature_index][n_vector_index];
00274 }
00275 
00276 std::vector<long> NPclassify::getParents()
00277 {
00278   return parent;
00279 }
00280 
00281 std::vector<std::vector<long> > NPclassify::getChildren()
00282 {
00283   return childMap;
00284 }
00285 
00286 std::vector<std::vector<long> > NPclassify::getBoundingBoxes()
00287 {
00288   std::vector<long> box(4,0);
00289   std::vector<std::vector<long> > boundingBox(stems,box);
00290 
00291   for(int ix = 0; ix < spaceSize; ix++)
00292   {
00293     if(revStem[ix] == false)
00294     {
00295       if(lowDensity[ix] == false)
00296         //&& (classSize[masterIndex[ix]] > hardClassSize))
00297       {
00298         if(boundingBox[masterIndex[ix]][0] == 0)
00299           boundingBox[masterIndex[ix]][0] = (long)Space[ix][0];
00300         else
00301           if(boundingBox[masterIndex[ix]][0] < Space[ix][0])
00302             boundingBox[masterIndex[ix]][0] = (long)Space[ix][0];
00303         if(boundingBox[masterIndex[ix]][1] == 0)
00304           boundingBox[masterIndex[ix]][1] = (long)Space[ix][1];
00305         else
00306           if(boundingBox[masterIndex[ix]][1] < Space[ix][1])
00307             boundingBox[masterIndex[ix]][1] = (long)Space[ix][1];
00308         if(boundingBox[masterIndex[ix]][2] == 0)
00309           boundingBox[masterIndex[ix]][2] = (long)Space[ix][0];
00310         else
00311           if(boundingBox[masterIndex[ix]][2] > Space[ix][0])
00312             boundingBox[masterIndex[ix]][2] = (long)Space[ix][0];
00313         if(boundingBox[masterIndex[ix]][3] == 0)
00314           boundingBox[masterIndex[ix]][3] = (long)Space[ix][1];
00315         else
00316           if(boundingBox[masterIndex[ix]][3] > Space[ix][1])
00317             boundingBox[masterIndex[ix]][3] = (long)Space[ix][1];
00318       }
00319     }
00320   }
00321   return boundingBox;
00322 }
00323 
00324 void NPclassify::metaClassify(int objects)
00325 {
00326   // find the first n links that meet that training criteria
00327   // find their statistics
00328   // open file to save tab delim data to
00329   std::ofstream outfile("train_set.dat",std::ios::app);
00330 
00331   // create statistics
00332 
00333   for(int ix = 0; ix < spaceSize; ix++)
00334   {
00335     trainMeasure[ix] = distance[ix]*(childMapTot[ix]/trainChildWeight);
00336     selected[ix] = false;
00337   }
00338 
00339   // find the n best candidates
00340   for(int n = 0; n < objects; n++)
00341   {
00342     int init = 0;
00343     for(int ix = 0; ix < spaceSize; ix++)
00344     {
00345       if(selected[ix] == false)
00346       {
00347         if(init == 0)
00348         {
00349           idealLinks[n] = ix;
00350           init = 1;
00351         }
00352         else
00353         {
00354           if(trainMeasure[ix] > trainMeasure[idealLinks[n]])
00355           {
00356             idealLinks[n] = ix;
00357           }
00358         }
00359       }
00360     }
00361     //std::cout << "FOUND " << idealLinks[n] << " " <<  distance[ idealLinks[n]]
00362     //              << " " << childMapTot[ idealLinks[n]] << "\n";
00363     selected[idealLinks[n]] = true;
00364   }
00365 
00366   // find there stats as they apply to the current scene
00367   // find min child and distance for nodes
00368   int init = 0;
00369   for(int n = 0; n < objects; n++)
00370   {
00371     if(init == 0)
00372     {
00373       minDist = idealLinks[n];
00374       minChild = idealLinks[n];
00375       init = 1;
00376     }
00377     else
00378     {
00379       if(distance[idealLinks[n]] < distance[minDist])
00380       {
00381         minDist = idealLinks[n];
00382       }
00383       if(childMapTot[idealLinks[n]] <  childMapTot[minChild])
00384       {
00385         minChild = idealLinks[n];
00386       }
00387     }
00388   }
00389   long returnStems = stems;
00390   for(int i = 0; i < stems; i++)
00391   {
00392     if(classSize[i] <= hardClassSize)
00393     {
00394       --returnStems;
00395     }
00396   }
00397 
00398   //std::cout << "CALC " << distance[minDist] << " - " <<  meanDistance
00399   //            << " / " << stdDistance << "\n";
00400 
00401   distanceCut = (distance[minDist] - meanDistance)/stdDistance;
00402   childCut = childMapTot[minChild]/meanChildMap;
00403   //std::cout << "distance " << distanceCut
00404   //            << " children " << childCut << "\n";
00405   outfile << spaceSize << "\t" << meanDensity << "\t"
00406           << objects << "\t" << distanceCut << "\t"
00407           << childCut << "\t" << returnStems << "\n";
00408 
00409   outfile.close();
00410 }
00411 
00412 // *****************************************
00413 // PRIVATE METHODS
00414 // *****************************************
00415 
00416 void NPclassify::convolveSpace()
00417 {
00418   // find distance between all points as an n^2 alg. Sum these for all
00419   // points to determine a points density measure
00420 
00421   for(int ix = 0; ix < spaceSize; ix++)
00422   {
00423     children[ix] = 0;
00424     revStem[ix] = false;
00425     for(int iy = 0; iy < spaceSize; iy++)
00426     {
00427       if(ix != iy)
00428       {
00429         Dis[ix][iy] = 0;
00430         // get distance between these two points
00431         for(unsigned int px = 0; px < Space[ix].size(); px++)
00432         {
00433             Dis[ix][iy] = Dis[ix][iy] +
00434               pow((Space[ix][px] - Space[iy][px]),2);
00435         }
00436         // find distance as sqrt(sum(sqared distances))
00437         // take the inverse distance 1/D
00438         // Dis[ix][iy] = sqrt(D[ix][iy]);
00439         if(Dis[ix][iy] != 0)
00440           D[ix][iy] = 1/sqrt(Dis[ix][iy]);
00441         // find polynomial distance
00442 
00443         D[ix][iy] = Con1*D[ix][iy] + pow((Con2*D[ix][iy]),2) +
00444           pow((Con3*D[ix][iy]),3);
00445       }
00446 
00447       density[ix] += D[ix][iy];
00448     }
00449     //std::cerr << "Density " << ix << " is " << density[ix] << "\n";
00450     //std::cerr << "PDensity " << ix << " is " << polyDensity[ix] << "\n";
00451   }
00452 }
00453 
00454 
00455 void NPclassify::convolveSpace2()
00456 {
00457   // find distance between all points as an n^2 alg. Sum these for all
00458   // points to determine a points density measure
00459 
00460   for(int ix = 0; ix < spaceSize; ix++)
00461   {
00462     children[ix] = 0;
00463     revStem[ix] = false;
00464     for(int iy = 0; iy < ix; iy++)
00465     {
00466         Dis[ix][iy] = 0;
00467         // get distance between these two points
00468         for(unsigned int px = 0; px < Space[ix].size(); px++)
00469         {
00470             Dis[ix][iy] = Dis[ix][iy] +
00471               pow((Space[ix][px] - Space[iy][px]),2);
00472         }
00473         // find distance as sqrt(sum(sqared distances))
00474         // take the inverse distance 1/D
00475         if(Dis[ix][iy] != 0)
00476           density[ix] += 1/sqrt(Dis[ix][iy]);
00477     }
00478     for(int iy = ix+1; iy < spaceSize; iy++)
00479     {
00480         Dis[ix][iy] = 0;
00481         // get distance between these two points
00482         for(unsigned int px = 0; px < Space[ix].size(); px++)
00483         {
00484             Dis[ix][iy] = Dis[ix][iy] +
00485               pow((Space[ix][px] - Space[iy][px]),2);
00486         }
00487         // find distance as sqrt(sum(sqared distances))
00488         // take the inverse distance 1/D
00489         if(Dis[ix][iy] != 0)
00490           density[ix] += 1/sqrt(Dis[ix][iy]);
00491     }
00492     //std::cerr << "Density " << ix << " is " << density[ix] << "\n";
00493     //std::cerr << "PDensity " << ix << " is " << polyDensity[ix] << "\n";
00494   }
00495 }
00496 
00497 void NPclassify::linkSpace()
00498 {
00499   // link points together. Take the closest point that is higher in
00500   // density
00501 
00502   // find mean density
00503   sum = 0; sumSquares = 0;
00504   for(int ix = 0; ix < spaceSize; ix++)
00505   {
00506     sum += density[ix];
00507   }
00508   meanDensity = sum/spaceSize;
00509   for(int ix = 0; ix < spaceSize; ix++)
00510   {
00511     sumSquares += pow((meanDensity - density[ix]),2);
00512   }
00513   stdDensity = sqrt(sumSquares/spaceSize);
00514   //std::cout << "meanDensity " << meanDensity << "\n";
00515   //std::cout << "stdDensity " << stdDensity << "\n";
00516   thresh3 = (preDenWeight1*meanDensity) + (preDenWeight2*pow(meanDensity,2));
00517   for(int ix = 0; ix < spaceSize; ix++)
00518   {
00519     if(density[ix] < thresh3)
00520       lowDensity[ix] = true;
00521     else
00522       lowDensity[ix] = false;
00523   }
00524 
00525   stems = 0;
00526   for(int ix = 0; ix < spaceSize; ix++)
00527   {
00528     children[ix] = 0;
00529   }
00530 
00531   for(int ix = 0; ix < spaceSize; ix++)
00532   {
00533     distance[ix] = 0;
00534     parent[ix] = -1;
00535     if(lowDensity[ix] == false)
00536     {
00537       for(int iy = 0; iy < spaceSize; iy++)
00538       {
00539         if(lowDensity[iy] == false)
00540         {
00541           if(ix != iy)
00542           {
00543             if(density[iy] > density[ix])
00544             {
00545               if(distance[ix] == 0)
00546               {
00547                 distance[ix] = Dis[ix][iy];
00548                 parent[ix] = iy;
00549               }
00550               else
00551               {
00552                 if(Dis[ix][iy] < distance[ix])
00553                 {
00554                   distance[ix] = Dis[ix][iy];
00555                   parent[ix] = iy;
00556                 }
00557               }
00558             }
00559           }
00560         }
00561       }
00562 
00563       // this guy has no parent. Label him as a stem
00564       if(parent[ix] == -1)
00565       {
00566         stem[stems] = ix;
00567         stems++;
00568         revStem[ix] = true;
00569         maxDensity = density[ix];
00570       }
00571       else
00572       {
00573         child[parent[ix]][children[parent[ix]]] = ix;
00574         children[parent[ix]]++;
00575       }
00576     }
00577     ///    else  // Compiler says: value computed is not used
00578     ///{
00579     ///  parent[ix] == -2;
00580     ///}
00581     //std::cerr << "LINKED " << ix << " TO " << parent[ix] << "\n";
00582   }
00583 
00584   // quick check for children. Your a root if you have none.
00585   roots = 0;
00586   for(int ix = 0; ix < spaceSize; ix++)
00587   {
00588     if(children[ix] == 0)
00589     {
00590       root[roots] = ix;
00591       roots++;
00592     }
00593   }
00594 }
00595 
00596 void NPclassify::mapSpace()
00597 {
00598   for(int ix = 0; ix < spaceSize; ix++)
00599   {
00600     for(int C = 0; C < children[ix]; C++)
00601     {
00602       childMap[ix][C] = child[ix][C];
00603       childMapTot[ix]++;
00604     }
00605   }
00606   //std::cerr << "CREATED initial map\n";
00607 
00608   notDone = true;
00609 
00610   // iterate linking parents and children until no more linking can be done
00611   // >retarded linking
00612   iteration = 0;
00613   while(notDone == true)
00614   {
00615     notDone = false;
00616     for(int ix = 0; ix < spaceSize; ix++)
00617     {
00618       // don't bother with this node if done
00619       if(childMapDone[ix] == false)
00620       {
00621         // my children
00622         for(int C = 0; C < childMapTot[ix]; C++)
00623         {
00624           // my childrens children
00625           for(int C2 = 0; C2 < childMapTot[childMap[ix][C]]; C2++)
00626           {
00627             // check to make sure we don't add twice
00628             bool found = false;
00629             //std::cerr << "TRYING " << childMap[childMap[ix][C]][C2]
00630             //              << " AGAINST " << ix << "\n";
00631             for(int CH = 0; CH < childMapTot[ix]; CH++)
00632             {
00633               if(childMap[ix][CH] == childMap[childMap[ix][C]][C2])
00634               {
00635                 found = true;
00636               }
00637             }
00638             if(found == false)
00639             {
00640               childMap[ix][childMapTot[ix]] =
00641                 childMap[childMap[ix][C]][C2];
00642               childMapTot[ix]++;
00643             }
00644           }
00645         }
00646       }
00647       // if I added anyone since the last iteration. Do another iteration.
00648       // stop if no one was added this iteration
00649       if(iteration > 0)
00650       {
00651         if(childMapTot[ix] != childMapTotLast[ix])
00652         {
00653           //std::cerr << "NOT DONE\n";
00654           notDone = true;
00655         }
00656         else
00657         {
00658           //std::cerr << "DONE\n";
00659           childMapDone[ix] = true;
00660         }
00661       }
00662       childMapTotLast[ix] = childMapTot[ix];
00663     }
00664     if(iteration == 0)
00665     {
00666       //std::cerr << "NOT DONE (i1)\n";
00667       notDone = true;
00668     }
00669     iteration++;
00670   }
00671 }
00672 
00673 void NPclassify::analizeSpace()
00674 {
00675 
00676   // find mean distance
00677   sum = 0; sumSquares = 0;
00678   for(int ix = 0; ix < spaceSize; ix++)
00679   {
00680     sum += distance[ix];
00681   }
00682   meanDistance = sum/spaceSize;
00683   for(int ix = 0; ix < spaceSize; ix++)
00684   {
00685     sumSquares += pow((meanDistance - distance[ix]),2);
00686   }
00687   stdDistance = sqrt(sumSquares/spaceSize);
00688   //std::cout << "Mean Dist " << meanDistance << " std " << stdDistance << "\n";
00689   // find the mean number of children
00690   sum = 0; sumSquares = 0;
00691   for(int ix = 0; ix < spaceSize; ix++)
00692   {
00693     sum += children[ix];
00694   }
00695   meanChildren = sum/spaceSize;
00696   for(int ix = 0; ix < spaceSize; ix++)
00697   {
00698     sumSquares += pow((meanChildren - children[ix]),2);
00699   }
00700   stdChildren = sqrt(sumSquares/spaceSize);
00701   //std::cout << "Mean Children " << meanChildren
00702   //            <<" std " << stdChildren << "\n";
00703   // find the mean number of all subordinates (grandchildren etc.)
00704   //            << " std " << stdChildren << "\n";
00705   sum = 0; sumSquares = 0;
00706   for(int ix = 0; ix < spaceSize; ix++)
00707   {
00708     sum += childMapTot[ix];
00709   }
00710   meanChildMap = sum/spaceSize;
00711   for(int ix = 0; ix < spaceSize; ix++)
00712   {
00713     sumSquares += pow((meanChildMap - childMapTot[ix]),2);
00714   }
00715   stdChildMap = sqrt(sumSquares/spaceSize);
00716   //std::cout << "Mean Children Tot " << meanChildMap
00717   //            << " std " << stdChildMap << "\n";
00718 
00719 }
00720 
00721 void NPclassify::evolveSpace()
00722 {
00723   //initial threshold is a function of standard deviation and a weight
00724   //and number of children and a weight for that
00725 
00726 
00727 
00728   // use polynomial optimized (linear regression) thresholds
00729   thresh1 = (polyDensObjectCut1*meanDensity+
00730                polyDensObjectCut2*pow(meanDensity,(double)2.0)+
00731                polyDensObjectCut3*pow(meanDensity,(double)3.0)) /
00732     (stdDensity+1);
00733 
00734     //>>rev A
00735     //thresh2 = (polySpaceChildCut1*spaceSize+
00736   //               polySpaceChildCut2*pow((double)spaceSize,(double)2.0)+
00737   //               polySpaceChildCut3*pow((double)spaceSize,(double)3.0));// *
00738       //(stdDensity+1);
00739     //>>rev A
00740 
00741   thresh2 = (CWeight1*meanChildMap) - (CWeight2*pow(meanChildMap,2));
00742   //std::cout << "THRESH1 " << thresh1 << " THRESH2 " << thresh2 << "\n";
00743   thresh3 = (DenWeight1*stdDensity) + (DenWeight2*pow(stdDensity,2));
00744   thresh4 = (DWeight1*stdDistance) + (DWeight2*pow(stdDistance,2));
00745   for(int ix = 0; ix < spaceSize; ix++)
00746   {
00747     measure1 = density[ix] - meanDensity;
00748     if((measure1 < 0) && (measure1 < thresh3))
00749       lowDensity[ix] = true;
00750     // How many std are you from the mean link distance. Use a weight that
00751     // signifies how far off you can be
00752     // look at both intre and inter class variance
00753     measure1 = distance[ix] - meanDistance;
00754     measure2 = meanDensity - density[ix];
00755     //std::cout << measure1 << " > " << thresh4 << "\t"
00756     //          << measure2 << " > " << thresh1 << "\t"
00757     //          << childMapTot[ix] << " > " << thresh2 << "\t"
00758     //          << distance[ix] << " > " << hardLinkSize << "\n";
00759 
00760     if((((measure1 > thresh4) || (measure2 > thresh1))
00761         && (childMapTot[ix] > thresh2)) || (distance[ix] > hardLinkSize))
00762     {
00763       if(lowDensity[ix] == false)
00764       {
00765         // how many grandchildren do you have compaired with the mean
00766         // make sure you have lots. Remove outliers
00767         stem[stems] = ix;
00768         //std::cerr << "STEM " << ix << "\n";
00769         stems++;
00770         revStem[ix] = true;
00771       }
00772     }
00773   }
00774   //std::cout << "FIRST ROUND STEMS: " << stems << "\n";
00775   computeMasters();
00776 }
00777 
00778 void NPclassify::analizeInterSpace()
00779 {
00780   // find masters, the class clusters
00781   // compute interclass variance and mean
00782   for(int i = 0; i < stems; i++)
00783   {
00784     meanInterDistance[i] = 0;
00785     stdInterDistance[i] = 0;
00786     meanInterChild[i] = 0;
00787     stdInterChild[i] = 0;
00788     if(classSize[i] == 0)
00789       classSize[i] = 1;
00790   }
00791   //first refine how many children are inside my class
00792   for(int ix = 0; ix < spaceSize; ix++)
00793   {
00794     childInterCount[ix] = 0;
00795     if(lowDensity[ix] == false)
00796     {
00797       for(int C = 0; C < childMapTot[ix]; C++)
00798       {
00799         // me and my decendant have the same master
00800         if(masterIndex[ix] == masterIndex[childMap[ix][C]])
00801         {
00802           childInterMap[ix][childInterCount[ix]] = childMap[ix][C];
00803           childInterCount[ix]++;
00804         }
00805       }
00806     }
00807   }
00808 
00809   // find mean for interclass statistics
00810   for(int ix = 0; ix < spaceSize; ix++)
00811   {
00812     if((revStem[ix] == false) && (lowDensity[ix] == false))
00813     {
00814       meanInterDistance[masterIndex[ix]] += distance[ix];
00815       meanInterDensity[masterIndex[ix]] += density[ix];
00816       meanInterChild[masterIndex[ix]] += childInterCount[ix];
00817     }
00818   }
00819 
00820   for(int i = 0; i < stems; i++)
00821   {
00822     //std::cout << "Class Size " << classSize[i] << "\n";
00823     meanInterDistance[i] = meanInterDistance[i]/classSize[i];
00824     meanInterDensity[i] = meanInterDensity[i]/classSize[i];
00825     meanInterChild[i] = meanInterChild[i]/classSize[i];
00826     //std::cout << "meanInterDistance " << meanInterDistance[i] << "\n";
00827     //std::cout << "meanInterDensity " << meanInterDensity[i] << "\n";
00828     //std::cout << "meanInterChild " << meanInterChild[i] << "\n";
00829   }
00830 
00831   for(int ix = 0; ix < spaceSize; ix++)
00832   {
00833     if((revStem[ix] == false) && (lowDensity[ix] == false))
00834     {
00835       stdInterDistance[masterIndex[ix]]
00836         += pow((meanInterDistance[ix] - distance[ix]),2);
00837       stdInterDensity[masterIndex[ix]]
00838         += pow((meanInterDensity[ix] - density[ix]),2);
00839       stdInterChild[masterIndex[ix]]
00840         += pow((meanInterChild[ix] - childInterCount[ix]),2);
00841     }
00842   }
00843   for(int i = 0; i < stems; i++)
00844   {
00845     stdInterDistance[i] = sqrt(stdInterDistance[i]/classSize[i]);
00846 
00847     stdInterDensity[i] = sqrt(stdInterDensity[i]/classSize[i]);
00848 
00849     stdInterChild[i] = sqrt(stdInterChild[i]/classSize[i]);
00850     //std::cout << "stdInterDistance " << stdInterDistance[i] << "\n";
00851     //std::cout << "stdInterDensity " << stdInterDensity[i] << "\n";
00852     //std::cout << "stdInterChild " << stdInterChild[i] << "\n";
00853   }
00854 }
00855 
00856 void NPclassify::evolveInterSpace()
00857 {
00858   //initial threshold is a function of standard deviation and a weight
00859   //and number of children and a weight for that
00860   for(int ix = 0; ix < spaceSize; ix++)
00861   {
00862     thresh3 = ((IDWeight1*stdInterDistance[masterIndex[ix]])
00863                + (IDWeight2*pow(stdInterDistance[masterIndex[ix]],2)))
00864       *((stdInterDensity[masterIndex[ix]]+1)*.2);
00865       //(stdDensity+1);
00866     thresh2 = ((ICWeight1*(1+meanInterChild[masterIndex[ix]]))
00867                - (ICWeight2*pow((1+meanInterChild[masterIndex[ix]]),2)))
00868       *(meanInterDensity[masterIndex[ix]]+1);
00869       //(stdDensity+1);
00870     // thresh2 = thresh2 * density[ix];
00871     // How many std are you from the mean link distance. Use a weight that
00872     // signifies how far off you can be
00873     // look at both intre and inter class variance
00874     measure1 = distance[ix] - meanInterDistance[masterIndex[ix]];
00875     //if((measure1 > thresh3) && (childInterCount[ix] > thresh2))
00876     //std::cout << measure1 << " > " <<  thresh3 << "\t"
00877     //          << childInterCount[ix] << " > " << hardClassSize << "\t"
00878     //          << childInterCount[ix] << " > "
00879     //          << (ICWeight1*meanInterDensity[masterIndex[ix]]) << "\n";
00880     if((measure1 > thresh3) && (childInterCount[ix] > hardClassSize) &&
00881        (childInterCount[ix]  > (ICWeight1*meanInterDensity[masterIndex[ix]])))
00882     {
00883       // how many grandchildren do you have compaired with the mean
00884       // make sure you have lots. Remove outliers
00885       stem[stems] = ix;
00886       stems++;
00887       revStem[ix] = true;
00888     }
00889   }
00890   //std::cout << "NEXT ROUND STEMS: " << stems << "\n";
00891   computeMasters();
00892 }
00893 
00894 void NPclassify::computeMasters()
00895 {
00896   // find my masters, form discrete classes
00897 
00898   for(int ix = 0; ix < spaceSize; ix++)
00899   {
00900     master[ix] = 0;
00901     classSize[ix] = 1;
00902   }
00903   for(int i = 0; i < stems; i++)
00904   {
00905     for(int j = 0; j < childMapTot[stem[i]]; j++)
00906     {
00907       if(master[childMap[stem[i]][j]] == 0)
00908       {
00909         master[childMap[stem[i]][j]] = stem[i];
00910         masterIndex[childMap[stem[i]][j]] = i;
00911       }
00912       else
00913       {
00914         for(int k = 0; k < childMapTot[master[childMap[stem[i]][j]]]; k++)
00915         {
00916           if(childMap[master[childMap[stem[i]][j]]][k] == stem[i])
00917           {
00918             master[childMap[stem[i]][j]] = stem[i];
00919             masterIndex[childMap[stem[i]][j]] = i;
00920           }
00921         }
00922       }
00923     }
00924   }
00925   // structure class list
00926   for(int ix = 0; ix < spaceSize; ix++)
00927   {
00928     Class[masterIndex[ix]][classSize[masterIndex[ix]]] = ix;
00929     classSize[masterIndex[ix]]++;
00930   }
00931 }
00932 
00933 void NPclassify::resizeSpace()
00934 {
00935   // resize vectors to default size initially
00936   // we suck memory because we care!!
00937   //std::cerr << "RESIZING ALL VECTORS TO: " << (defaultSize+spaceSize) << "\n";
00938   children.resize(defaultSize+spaceSize,0);
00939   parent.resize(defaultSize+spaceSize);
00940   childMapTot.resize(defaultSize+spaceSize);
00941   childMapTotLast.resize(defaultSize+spaceSize);
00942   stem.resize(defaultSize+spaceSize);
00943   root.resize(defaultSize+spaceSize);
00944   master.resize(defaultSize+spaceSize);
00945   masterIndex.resize(defaultSize+spaceSize);
00946   classSize.resize(defaultSize+spaceSize);
00947   childInterCount.resize(defaultSize+spaceSize);
00948   idealLinks.resize(defaultSize+spaceSize);
00949   density.resize(defaultSize+spaceSize);
00950   distance.resize(defaultSize+spaceSize);
00951   meanInterDistance.resize(defaultSize+spaceSize);
00952   meanInterDensity.resize(defaultSize+spaceSize);
00953   meanInterChild.resize(defaultSize+spaceSize);
00954   stdInterDistance.resize(defaultSize+spaceSize);
00955   stdInterDensity.resize(defaultSize+spaceSize);
00956   stdInterChild.resize(defaultSize+spaceSize);
00957   trainMeasure.resize(defaultSize+spaceSize);
00958   revStem.resize(defaultSize+spaceSize,false);
00959   childMapDone.resize(defaultSize+spaceSize);
00960   lowDensity.resize(defaultSize+spaceSize);
00961   selected.resize(defaultSize+spaceSize);
00962 
00963   std::vector<long> tempLong(defaultSize,0);
00964   std::vector<double> tempDouble(defaultSize,0);
00965   child.resize(defaultSize+spaceSize,tempLong);
00966   childMap.resize(defaultSize+spaceSize,tempLong);
00967   childInterMap.resize(defaultSize+spaceSize,tempLong);
00968   Class.resize(defaultSize+spaceSize,tempLong);
00969   Dis.resize(defaultSize+spaceSize,tempDouble);
00970   D.resize(defaultSize+spaceSize,tempDouble);
00971   Space.resize(defaultSize+spaceSize,tempDouble);
00972   //std::cerr << "DONE\n";
00973 }
00974 
00975 // ######################################################################
00976 /* So things look consistent in everyone's emacs... */
00977 /* Local Variables: */
00978 /* indent-tabs-mode: nil */
00979 /* End: */
Generated on Sun May 8 08:07:03 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3