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