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: */