Diploma Thesis Percolation Simulation
C++ Sourcecode Documentation

www.AndreasKrueger.de/thesis/code

Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

divide_and_conquer.h

Go to the documentation of this file.
00001 
00002 // divide_and_conquer.h
00003 // divides spheres in parts, solves the partial problems 
00004 // and combines the cluster
00005 //
00006 // Andreas Krueger 14.7.2000
00007 // v2.0 , last changes: 26.8.2000
00008 //
00009 
00010 namespace counters {
00011         using analyze::edgespheres;
00012         using analyze::analyze_clusters;
00013         using analyze::erasehisto;
00014         using analyze::makehistogram;
00015 
00016 
00017 // divides list original->lowerlist+upperlist, 
00018 //      depending on value 'border' in coordinate 'direction'
00019 void divide_all_spheres (sphere *array,
00020                                                  NUMLIST & original, 
00021                                                  NUMLIST & lowerlist, 
00022                                                  NUMLIST & upperlist,
00023                                                  COORDFLOAT border,
00024                                                  int direction){
00025 
00026         NUMLIST::iterator iter1;
00027 
00028         for (iter1 =  original.begin(); iter1 != original.end(); ++iter1){
00029                 if ( lower(array[*iter1].c, border, direction)) 
00030                         lowerlist.insert(lowerlist.end(), *iter1);
00031                 else upperlist.insert(upperlist.end(), *iter1);
00032         }
00033 }
00034 
00035 
00036 
00037 #ifndef TIMEMEASUREMENT
00038 
00039 NUMBER combine (sphere* spheres, 
00040                                          NUMLIST &sph1, 
00041                                          NUMLIST &sph2, 
00042                                          cluson* clst, 
00043                                          NUMBER firstclno, 
00044                                          NUMBER c1,
00045                                          NUMBER c2,
00046                                          COORDFLOAT border,
00047                                          int direction)
00048 {
00049         if (sph1.empty() || sph2.empty()) return c2;            // if one of the parts is empty, 
00050                                                                                                                                         // do nothing
00051 
00052         sphere s1=spheres[*sph1.begin()]; sphere s2=spheres[*sph2.begin()];
00053         sphere temp=s1; // for a faster overlap-check
00054 
00055         if (s1.clno  > s2.clno ) {
00056                 errorout("combine is not possible, \nbecause clusno's in first list greater than in second list");
00057                 cout <<s1.clno  <<"\t"<< s2.clno<<endl;
00058                 exit (1);
00059         }
00060         if (lower(s2.c-s1.c, 0,direction)) {
00061                 errorout("combine is not possible, \nbecause coordinates of first list are higher than of second list");
00062                 cout <<"(in direction "<<direction<<" ): s1.c="<<s1.c<<" s2.c="<<s2.c<<endl;
00063                 exit(1);
00064         }
00065 
00066         REAL radius1=find_biggestradius(spheres,sph1);
00067         REAL radius2=find_biggestradius(spheres,sph2);
00068         REAL radius=( (radius1 > radius2) ? radius1 : radius2);
00069 
00070         NUMLIST e1, e2;
00071         edgespheres(spheres, sph1, e1,border, 2*radius, direction);
00072         edgespheres(spheres, sph2, e2,border, 2*radius, -direction);
00073         // cout <<"number of edgespheres: "<< e1.size()<<"\t"<<e2.size()<<endl;
00074 
00075         // now find all overlapping edgespheres -> clstoverlap[ ]
00076         // = list of directly overlapping clno's (both ways "forwards" and "backwards"!)
00077         // !!! one clno might be mentioned several times !!!
00078 
00079         clusterneighbours *clstoverlap = new clusterneighbours[c2-firstclno];   
00080                                 // for the clusternumbers   [firstclno;...c1.............;c2-1]
00081                                 // use the (smaller) array  [0;...........c1-firstclno...;c2-firstclno-1]
00082 
00083         NUMLIST::iterator esph1, esph2;
00084 
00085         // idea: sort first perpendicular to cutline, 
00086         // then compare only those within a certain distance
00087         // but at the moment, this checks _all_ edgespheres:
00088         for (esph1=e1.begin();esph1!=e1.end();esph1++){
00089                 for (esph2=e2.begin();esph2!=e2.end();esph2++){
00090                         s1= spheres[*esph1];
00091                         s2= spheres[*esph2];
00092                         if (overlap2 (s1,s2,temp)) {            // overlapping spheres -> overlapping clusters
00093                                 clstoverlap[s1.clno-firstclno].clusno.push_back ( s2.clno); // forwards
00094                                 clstoverlap[s2.clno-firstclno].clusno.push_back ( s1.clno); // backwards
00095                         }
00096                 }
00097         }
00098 
00099         e1.clear(); e2.clear();
00100 
00101         // now follow all cluster-connections in clstoverlap[] 
00102         // delete the multiple entries
00103         // and collect all clno's of overlapping clusters 
00104         // in the list with the smallest clusternumber
00105 
00106         NUMLIST::iterator nneighb ;
00107         NUMBER clno;
00108         for (clno=firstclno;clno<=c1-1;clno++){
00109                 NUMLIST &neighbours=clstoverlap[clno-firstclno].clusno; // alias (!)
00110 
00111                 if (! neighbours.empty() ){                                                     // no overlap
00112                         if ( *(neighbours.begin()) != -1)                               // already counted
00113                         {
00114                                 for (nneighb=neighbours.begin();nneighb!=neighbours.end();nneighb++){
00115 
00116                                         while ( (*nneighb==clno) || (*(clstoverlap[*nneighb-firstclno].clusno.begin())==-1 )) {
00117                                                 nneighb=neighbours.erase(nneighb);
00118                                                 if (nneighb==neighbours.end()) break;
00119                                         }
00120                                         if (nneighb==neighbours.end()) break;
00121 
00122                                         neighbours.splice(neighbours.end(), clstoverlap[*nneighb-firstclno].clusno);
00123                                         clstoverlap[*nneighb-firstclno].clusno.push_front(-1);
00124                                 }
00125                         }
00126                         else    neighbours.clear();
00127                 }
00128         }
00129 
00130 
00131 /*
00132         // the following is not necessary if the tests below are switched off
00133         // because the combination is done in [firstclno;c1-1] only
00134         //
00135         // clear the backwards connections (that were set to -1 in the above process)
00136         for (clno=c1;clno<=c2-1;clno++){
00137                 NUMLIST &neighbours=clstoverlap[clno-firstclno].clusno; 
00138                 if ( neighbours.size() != 0 && *(neighbours.begin()) == -1 )  {
00139                         neighbours.clear();
00140                 }
00141         }
00142 
00143         // only a test (time-consuming!):
00144         // test if all self-references and "-1" have been erased
00145         NUMBER s;
00146         for (clno=firstclno;clno<=c2-1;clno++){
00147                 NUMLIST &neighbours=clstoverlap[clno-firstclno].clusno;
00148                 if ( neighbours.size()!=0 && (*(neighbours.begin()))  == -1)  {
00149                         error("ALARM: -1 left");
00150                         cout << "clno="<<clno<<endl;
00151                         cout << "firstclno="<<firstclno<<" c1="<<c1<<" c2="<<c2<<endl;
00152                         exit(1);
00153                 }
00154                 s=neighbours.size();
00155                 neighbours.remove(clno);
00156                 s=s-neighbours.size();
00157                 if (s !=0) {
00158                         error("still self-references in clusterlist");
00159                         cout << " clno="<<clno<<" # of self references=" <<s<<endl;
00160                         exit(1);
00161                 }
00162         }
00163 
00164         // only a test (time consuming!)
00165         // test if all the clusters have been combined
00166         // by looking for non-empty backwards connection lists
00167         for (clno = c1 ; clno<= c2-1;clno++){
00168                 if (clstoverlap[clno-firstclno].clusno.size()!= 0) {
00169                         error ("not found every connection during combining"); 
00170                         cout <<"clno="<<clno; 
00171                         cout <<" overlap["<<clno<<"].clusno.size = "<<clstoverlap[clno-firstclno].clusno.size()<<endl;
00172                         NUMLIST::iterator cl;
00173                         for (cl=clstoverlap[clno-firstclno].clusno.begin();cl!=clstoverlap[clno-firstclno].clusno.end();cl++){
00174                                 cout <<*cl<< " ";
00175                         }
00176                         cout <<endl; 
00177                         exit(1);
00178                 }
00179         }
00180         
00181   
00182         // show the resulting cluster combination
00183         cout <<"\ncombined clusters are"<<endl;
00184         for (clno=firstclno;clno<=c1-1;clno++){
00185 
00186                 NUMLIST &neighbours=clstoverlap[clno-firstclno].clusno;
00187                 if (! neighbours.empty() ){
00188                         cout <<"{"<< clno<<"+  ";
00189                         for (nneighb=neighbours.begin();nneighb!=neighbours.end();nneighb++){
00190                                 cout <<*nneighb<< " "<<flush;
00191                         }
00192                         cout <<"}\t"<<flush;
00193                 }
00194         }
00195 */
00196   
00197         // now combine the clusters of spheres according to clstoverlap
00198         // and set the right clusternumber to each sphere
00199 
00200         // idea: perhaps renumbering doesn't have to be done here, but below
00201 
00202         for (clno=firstclno;clno<=c1-1;clno++){
00203                 NUMLIST &neighbours=clstoverlap[clno-firstclno].clusno;
00204                 if (! neighbours.empty() ){
00205                         for (nneighb=neighbours.begin();nneighb!=neighbours.end();nneighb++){
00206                                 set_clusternumber (spheres, clst[*nneighb].sphlist,clno);               
00207                                 clst[clno].sphlist.splice(clst[clno].sphlist.end(), clst[*nneighb].sphlist);
00208                         }
00209                 }
00210         }
00211 
00212         delete[] clstoverlap;
00213 
00214 
00215         // clean clustertable of empty clusters
00216         // and set the right clno to each sphere
00217 
00218         NUMBER highest=c2-1;
00219 
00220         for (clno=firstclno;clno<=c2-1;clno++){
00221                 if (! clst[clno].sphlist.empty()) highest=clno;
00222                 else{
00223                         // find first non-empty 
00224                         NUMBER j;
00225                         for (j=clno+1;j<=c2-1;j++) if (! clst[j].sphlist.empty()) break;
00226                         if (j==c2) {clno=c2;break;}       // the rest is also empty
00227 
00228                         else{
00229                                 swapcluson(clst[clno],clst[j]);
00230                                 set_clusternumber (spheres, clst[clno].sphlist,clno);
00231                                 if (!clst[j].sphlist.empty()) {
00232                                         errorout ("error in getting rid of empty clusters (after swap)");
00233                                         cout <<"should be empty: clno j="<<j<<endl;
00234                                         cout <<"was swapped: clno ="<<clno<<endl;
00235                                         exit (1);
00236                                 }
00237                                 highest=clno;
00238                         }
00239                 }
00240         }
00241         c2=highest+1;     // first empty clusternumber
00242 
00243         return (c2);
00244 }
00245 
00246 
00247 
00248 #else // if TIMEMEASUREMENT wanted
00249 
00250 
00251 
00252 
00253 // global stop-clocks for TIMEMEASUREMENT
00254 class t_combine{
00255 public:
00256         clock_t checks;
00257         clock_t findedges;
00258         clock_t createobjects;
00259         clock_t edgesphere_ovrlap;
00260         clock_t ovrlpclst_relabel;
00261         clock_t clustersplice;
00262         clock_t cleanclustertable;
00263         t_combine(){checks=0; findedges=0; createobjects=0;
00264                             edgesphere_ovrlap=0;ovrlpclst_relabel=0;
00265                                 clustersplice=0; cleanclustertable=0;};
00266         clock_t sum(){return checks+findedges+createobjects+edgesphere_ovrlap+
00267                                                 ovrlpclst_relabel+clustersplice+cleanclustertable;};
00268 };
00269 t_combine tcom;
00270 
00271 NUMBER combine (sphere* spheres, 
00272                                          NUMLIST &sph1, 
00273                                          NUMLIST &sph2, 
00274                                          cluson* clst, 
00275                                          NUMBER firstclno, 
00276                                          NUMBER c1,
00277                                          NUMBER c2,
00278                                          COORDFLOAT border,
00279                                          int direction)
00280 {
00281         clock_t ttemp;
00282         ttemp=clock();
00283 
00284         if (sph1.empty() || sph2.empty()) return c2;            // if one of the parts is empty, 
00285                                                                                                                                         // do nothing
00286 
00287         sphere s1=spheres[*sph1.begin()]; sphere s2=spheres[*sph2.begin()];
00288         sphere temp=s1; // for a faster overlap-check
00289 
00290         if (s1.clno  > s2.clno ) {
00291                 errorout("combine is not possible, \nbecause clusno's in first list greater than in second list");
00292                 cout <<s1.clno  <<"\t"<< s2.clno<<endl;
00293                 exit (1);
00294         }
00295         if (lower(s2.c-s1.c, 0,direction)) {
00296                 errorout("combine is not possible, \nbecause coordinates of first list are higher than of second list");
00297                 cout <<"(in direction "<<direction<<" ): s1.c="<<s1.c<<" s2.c="<<s2.c<<endl;
00298                 exit(1);
00299         }
00300 
00301         REAL radius1=find_biggestradius(spheres,sph1);
00302         REAL radius2=find_biggestradius(spheres,sph2);
00303         REAL radius=( (radius1 > radius2) ? radius1 : radius2);
00304 
00305         tcom.checks+=clock()-ttemp;
00306         ttemp=clock();
00307 
00308         NUMLIST e1, e2;
00309         edgespheres(spheres, sph1, e1,border, 2*radius, direction);
00310         edgespheres(spheres, sph2, e2,border, 2*radius, -direction);
00311         // cout <<"number of edgespheres: "<< e1.size()<<"\t"<<e2.size()<<endl;
00312 
00313         // now find all overlapping edgespheres -> clstoverlap[ ]
00314         // = list of directly overlapping clno's (both ways "forwards" and "backwards"!)
00315         // !!! one clno might be mentioned several times !!!
00316 
00317         tcom.findedges+=clock()-ttemp;
00318         ttemp=clock();
00319         
00320         clusterneighbours *clstoverlap = new clusterneighbours[c2-firstclno];   
00321                                 // for the clusternumbers   [firstclno;...c1.............;c2-1]
00322                                 // use the (smaller) array  [0;...........c1-firstclno...;c2-firstclno-1]
00323 
00324         NUMLIST::iterator esph1, esph2;
00325 
00326 #ifndef BOXING_ON
00327 
00328         for (esph1=e1.begin();esph1!=e1.end();esph1++){
00329                 for (esph2=e2.begin();esph2!=e2.end();esph2++){
00330                         s1= spheres[*esph1];
00331                         s2= spheres[*esph2];
00332                         if (overlap2 (s1,s2,temp)) {            // overlapping spheres -> overlapping clusters
00333                                 clstoverlap[s1.clno-firstclno].clusno.push_back ( s2.clno); // forwards
00334                                 clstoverlap[s2.clno-firstclno].clusno.push_back ( s1.clno); // backwards
00335                         }
00336                 }
00337         }
00338 
00339         e1.clear(); e2.clear();
00340 
00341 #else // if BOXING_ON 
00342 
00343 // this has changed after boxing (START)
00344         int dim=getdim(spheres[e1.front()]);
00345 
00346         NUMBER nslots=GRIDSIZE/(4*radius); // heuristic: shouldn't probably be > .../(2*radius)
00347         nslots=nslots<1?1:nslots;
00348         NUMBER maxslots=(NUMBER) grid::maximal_slots_that_can_be_numbered(dim);
00349         //cout<<" |nsl:"<<nslots<<", maxsl:"<<maxslots<<"| ";
00350         nslots=nslots>maxslots?maxslots:nslots;
00351         NUMBER nboxes=pow(nslots,dim);
00352 
00353         std::vector<NUMLIST > leftbox, rightbox; 
00354         leftbox.resize(nboxes); rightbox.resize(nboxes); 
00355 
00356         tcom.createobjects+=clock()-ttemp;      
00357         ttemp=clock();
00358 
00359         NUMBER sn1=grid::spheres_into_boxes(spheres, e1, 0, GRIDSIZE, nslots, 2*radius, leftbox);
00360         NUMBER sn2=grid::spheres_into_boxes(spheres, e2, 0, GRIDSIZE, nslots, 2*radius, rightbox);
00361         if (sn1<0 || sn2<0) {
00362                 cerr<<"problems with boxing the spheres into the grid\n";
00363                 cerr<<"sn1="<<sn1<<" sn2="<<sn2<<" please write to cpp__at__AndreasKrueger__dot__de\n"<<endl;
00364                 waitanykey();
00365                 exit(1);
00366         }
00367         //cout<<" |sn1="<<sn1<<" sn2="<<sn2<<"| "<<flush;
00368 
00369         e1.clear(); e2.clear();
00370 
00371         NUMBER bn;
00372         for (bn=0;bn<nboxes;bn++){
00373 
00374                 for (esph1=leftbox[bn].begin();esph1!=leftbox[bn].end();esph1++){
00375                         for (esph2=rightbox[bn].begin();esph2!=rightbox[bn].end();esph2++){
00376                                 s1= spheres[*esph1];
00377                                 s2= spheres[*esph2];
00378                                 if (overlap2 (s1,s2,temp)) {            // overlapping spheres -> overlapping clusters
00379                                         clstoverlap[s1.clno-firstclno].clusno.push_back ( s2.clno); // forwards
00380                                         clstoverlap[s2.clno-firstclno].clusno.push_back ( s1.clno); // backwards
00381                                 }
00382                         }
00383                 }
00384         }
00385 
00386 // this has changed after boxing (END)
00387 
00388 #endif  // if BOXING_ON
00389 
00390 
00391         tcom.edgesphere_ovrlap+=clock()-ttemp;
00392 
00393 
00394         // now follow all cluster-connections in clstoverlap[] 
00395         // delete the multiple entries
00396         // and collect all clno's of overlapping clusters 
00397         // in the list with the smallest clusternumber
00398 
00399          ttemp=clock();
00400         NUMLIST::iterator nneighb ;
00401         NUMBER clno;
00402         for (clno=firstclno;clno<=c1-1;clno++){
00403                 NUMLIST &neighbours=clstoverlap[clno-firstclno].clusno; // alias (!)
00404 
00405                 if (! neighbours.empty() ){                                                     // no overlap
00406                         if ( *(neighbours.begin()) != -1)                               // already counted
00407                         {
00408                                 for (nneighb=neighbours.begin();nneighb!=neighbours.end();nneighb++){
00409 
00410                                         while ( (*nneighb==clno) || (*(clstoverlap[*nneighb-firstclno].clusno.begin())==-1 )) {
00411                                                 nneighb=neighbours.erase(nneighb);
00412                                                 if (nneighb==neighbours.end()) break;
00413                                         }
00414                                         if (nneighb==neighbours.end()) break;
00415 
00416                                         neighbours.splice(neighbours.end(), clstoverlap[*nneighb-firstclno].clusno);
00417                                         clstoverlap[*nneighb-firstclno].clusno.push_front(-1);
00418                                 }
00419                         }
00420                         else    neighbours.clear();
00421                 }
00422         }
00423  
00424         tcom.ovrlpclst_relabel+=clock()-ttemp;
00425         ttemp=clock();
00426 
00427         // now combine the clusters of spheres according to clstoverlap
00428         // and set the right clusternumber to each sphere
00429 
00430         // idea: perhaps renumbering doesn't have to be done here, but below
00431 
00432         for (clno=firstclno;clno<=c1-1;clno++){
00433                 NUMLIST &neighbours=clstoverlap[clno-firstclno].clusno;
00434                 if (! neighbours.empty() ){
00435                         for (nneighb=neighbours.begin();nneighb!=neighbours.end();nneighb++){
00436                                 set_clusternumber (spheres, clst[*nneighb].sphlist,clno);               
00437                                 clst[clno].sphlist.splice(clst[clno].sphlist.end(), clst[*nneighb].sphlist);
00438                         }
00439                 }
00440         }
00441 
00442         tcom.clustersplice+=clock()-ttemp;
00443 
00444          ttemp=clock();
00445         delete[] clstoverlap;
00446          tcom.createobjects+=clock()-ttemp;
00447 
00448         // clean clustertable of empty clusters
00449         // and set the right clno to each sphere
00450 
00451         ttemp=clock();
00452 
00453         NUMBER highest=c2-1;
00454 
00455         for (clno=firstclno;clno<=c2-1;clno++){
00456                 if (! clst[clno].sphlist.empty()) highest=clno;
00457                 else{
00458                         // find first non-empty 
00459                         NUMBER j;
00460                         for (j=clno+1;j<=c2-1;j++) if (! clst[j].sphlist.empty()) break;
00461                         if (j==c2) {clno=c2;break;}       // the rest is also empty
00462 
00463                         else{
00464                                 swapcluson(clst[clno],clst[j]);
00465                                 set_clusternumber (spheres, clst[clno].sphlist,clno);
00466                                 if (!clst[j].sphlist.empty()) {
00467                                         errorout ("error in getting rid of empty clusters (after swap)");
00468                                         cout <<"should be empty: clno j="<<j<<endl;
00469                                         cout <<"was swapped: clno ="<<clno<<endl;
00470                                         exit (1);
00471                                 }
00472                                 highest=clno;
00473                         }
00474                 }
00475         }
00476 
00477         tcom.cleanclustertable+=clock()-ttemp;
00478         ttemp=clock();
00479 
00480         c2=highest+1;     // first empty clusternumber
00481         return (c2);
00482 }
00483 
00484 #endif // TIMEMEASUREMENT
00485 
00486 
00487 // the first tests: divide once, twice, three times...
00488 
00489 // only dividing once, without analysis of histogram
00490 // used for divide_two_times & three_times
00491 NUMBER divide_once_count_and_combine (sphere* spheres, 
00492                                         sphere* temp,
00493                                         NUMLIST &all,
00494                                         cluson *clst,
00495                                         NUMBER firstclno,
00496                                         COORDFLOAT border,
00497                                         int direction) 
00498 {
00499 
00500         NUMBER c1,c2;
00501         NUMLIST sph1,sph2;
00502         divide_all_spheres(spheres, all, sph1,sph2,border,direction);
00503 
00504         c1=list_to_given_array_and_find_cluster(spheres, temp, sph1, firstclno);
00505         c2=list_to_given_array_and_find_cluster(spheres, temp, sph2, c1);
00506         cout <<"found "<<c1-firstclno<<" and "<<c2-c1<<" clusters ";
00507         cout <<"(c1="<<c1<<", c2="<<c2<<")";
00508 
00509         make_clusterlist_array (spheres, all, clst);
00510 
00511         c2=combine(spheres,sph1,sph2,clst,firstclno,c1,c2,border,direction);
00512         return (c2);
00513 }
00514 
00515 // divide once, count and analyze histogram
00516 NUMBER divide_once_count_and_analyze(sphere* spheres, 
00517                                                                 sphere* temp,
00518                                                                 NUMLIST &all,
00519                                                                 NUMBER N, 
00520                                                                 NUMBER *histogram, 
00521                                                                 NUMBER &biggestcl, 
00522                                                                 REAL &averagecl)
00523 {
00524 
00525         cluson *clusters=new cluson[N+1];
00526         NUMBER nextclno;
00527 
00528         nextclno=divide_once_count_and_combine (spheres, temp, all, clusters,1,GRIDSIZE/2, 1);
00529         cout <<" -> combined to: "<<nextclno-1<<" clusters"<<endl;
00530         
00531         NUMBER biggestcl_no=analyze_clusters (clusters, 1, nextclno-1,histogram,N,biggestcl,averagecl);
00532         
00533         delete[] clusters;
00534 
00535         return (biggestcl_no);
00536 }
00537 
00538 
00539 NUMBER divide_two_times_count_and_analyze(sphere* spheres, 
00540                                                                 sphere* temp,
00541                                                                 NUMLIST &all,
00542                                                                 NUMBER N, 
00543                                                                 NUMBER *histogram, 
00544                                                                 NUMBER &biggestcl, 
00545                                                                 REAL &averagecl)
00546 {
00547 
00548         cluson *clusters=new cluson[N+1];
00549 
00550         NUMBER nextclno1, nextclno2;
00551         NUMBER cl2;
00552         NUMLIST sph1,sph2;
00553 
00554         COORDFLOAT border1=GRIDSIZE/2;
00555 
00556         divide_all_spheres(spheres, all,sph1,sph2, border1,1);
00557 
00558          //cout <<"A) count clusters in left part..."<<endl;
00559          nextclno1=divide_once_count_and_combine (spheres, temp, sph1, clusters,1,border1, 2);
00560          cout <<" -> combined to: "<<nextclno1-1<<" clusters"<<endl;
00561 
00562          //cout <<"B) count clusters in right part..."<<endl;
00563          nextclno2=divide_once_count_and_combine (spheres, temp, sph2, clusters,nextclno1,border1, 2);
00564          cout <<" -> combined to: "<<nextclno2-nextclno1<<" clusters"<<endl;
00565         
00566         cout <<"Now combine the two results...";
00567         cl2=combine (spheres,sph1,sph2,clusters,1,nextclno1,nextclno2,border1,1);
00568         cout <<" -> combined to: "<<cl2-1<<" clusters"<<endl;
00569         
00570         NUMBER biggestcl_no=analyze_clusters (clusters, 1, cl2-1,histogram,N,biggestcl,averagecl);
00571         
00572         delete[] clusters;
00573 
00574         return (biggestcl_no);
00575 }
00576 
00577 NUMBER divide_three_times_count_and_analyze(sphere* spheres, 
00578                                                                 sphere* temp,
00579                                                                 NUMLIST &all,
00580                                                                 NUMBER N, 
00581                                                                 NUMBER *histogram, 
00582                                                                 NUMBER &biggestcl, 
00583                                                                 REAL &averagecl)
00584 {
00585         cluson *clusters=new cluson[N+1];
00586 
00587         NUMBER nextclno1, nextclno2;
00588         NUMBER cl1, cl2;
00589         NUMLIST sph1,sph2,sph3,sph4,sph5,sph6;
00590 
00591         COORDFLOAT border1=GRIDSIZE/2;
00592         COORDFLOAT border2=GRIDSIZE/4;
00593 
00594         divide_all_spheres(spheres, all, sph1,sph2,border1,1);
00595 
00596         divide_all_spheres(spheres, sph1,sph3,sph4,border1,2);
00597         nextclno1=divide_once_count_and_combine (spheres, temp, sph3, clusters,1,border1-border2, 1); cout<<endl;
00598          nextclno2=divide_once_count_and_combine (spheres, temp, sph4, clusters,nextclno1,border1-border2, 1); cout<<endl;
00599         cl1=combine (spheres,sph3,sph4,clusters,1,nextclno1,nextclno2,border1,2);
00600         cout <<" -> combined to: "<<cl1-1<<" clusters"<<endl;
00601         
00602         divide_all_spheres(spheres, sph2,sph5,sph6,border1,2);
00603          nextclno1=divide_once_count_and_combine (spheres, temp, sph5, clusters,cl1,border1+border2, 1); cout <<endl;
00604          nextclno2=divide_once_count_and_combine (spheres, temp, sph6, clusters,nextclno1,border1+border2, 1); cout<<endl;
00605         cl2=combine (spheres,sph5,sph6,clusters,cl1,nextclno1,nextclno2,border1,2);
00606         cout <<" -> combined to: "<<cl2-cl1<<" clusters"<<endl;
00607 
00608         cout <<"Now these two combined to: ";
00609         cl2=combine(spheres,sph1,sph2,clusters,1,cl1,cl2,border1,1);
00610         cout<<cl2-1<<" clusters"<<endl;
00611 
00612         NUMBER biggestcl_no=analyze_clusters (clusters, 1, cl2-1,histogram,N,biggestcl,averagecl);
00613 
00614         delete[] clusters;
00615 
00616         return (biggestcl_no);
00617 }
00618 
00619 
00620 
00621 // the divide d-times algo:
00622 // this algo divides the space into smaller square cells
00623 //
00624 // with the same number of cuts in each dimensional direction
00625 // -> cuts = dividings * dimension
00626 // #cells = 2^cuts = 2^( dividings * dimension)
00627 // advantage: easy to code
00628 // disadvantage: very big steps 
00629 //       4dim: 2 dividings -> 2^(4*2) = 256 boxes
00630 //             3 dividings -> 2^(4*3) = 4096 boxes
00631 //
00632 //
00633 // !!! NOT USED ANYMORE - only for testing !!!
00634 
00635 COUNTER maximal_dividings_in_one_coordinate(COORDFLOAT spacelength, REAL radius) {
00636         REAL boxlength=2*radius;
00637         REAL maximal_boxes_in_one_direction=spacelength/boxlength;
00638         REAL maximal_dividings=log(maximal_boxes_in_one_direction) / log (2);
00639         return ( (int) maximal_dividings );
00640 }
00641 
00642 NUMBER partcount (sphere* spheres,
00643                                   NUMLIST &all,
00644                                   COORDFLOAT l,
00645                                   COORDFLOAT r,
00646                                   COORDFLOAT lm,
00647                                   COORDFLOAT rm,
00648                                   COUNTER divstep,
00649                                   COUNTER divmax,
00650                                   int direction,
00651                                   int dimension,
00652                                   cluson *clusters,
00653                                   NUMBER firstclno)
00654 {
00655         NUMBER nextclno;
00656 
00657    if (divmax==0) 
00658         {
00659                 nextclno=list_to_temp_array_and_find_cluster(spheres, all, firstclno);
00660                 make_clusterlist_array (spheres, all, clusters);
00661                 return nextclno;
00662         }
00663    
00664         if ( direction==dimension ) {
00665                 if ( divstep==divmax ) {
00666                         NUMLIST s1, s2;
00667                         NUMBER ncl1, ncl2;
00668                         divide_all_spheres (spheres, all, s1,s2,(l+r)/2,direction);
00669                         //cout <<"\ndir="<<direction<<"\tborders l,r=\t"<<l<<"\t"<<r;
00670                         //cout <<"\t# of spheres="<<s1.size()<<" and "<<s2.size()<<endl;
00671                         ncl1=list_to_temp_array_and_find_cluster(spheres, s1, firstclno);
00672                         ncl2=list_to_temp_array_and_find_cluster(spheres, s2, ncl1);
00673                         make_clusterlist_array (spheres, all, clusters);
00674                         nextclno=combine(spheres, s1,s2,clusters,firstclno,ncl1,ncl2,(l+r)/2,direction);
00675                 }
00676                 else {
00677                         NUMLIST s1, s2;
00678                         NUMBER ncl1, ncl2;
00679                         divide_all_spheres (spheres, all, s1,s2,(l+r)/2,direction);
00680                         //cout <<"diV ";
00681                         ncl1=partcount(spheres, s1, l,(l+r)/2, lm,rm, divstep+1, divmax, direction,dimension, clusters, firstclno);
00682                         ncl2=partcount(spheres, s2, (l+r)/2,r, lm,rm, divstep+1, divmax, direction,dimension, clusters, ncl1);
00683                         nextclno=combine(spheres, s1,s2,clusters,firstclno,ncl1,ncl2,(l+r)/2,direction);
00684                 }
00685         }
00686 
00687         else {
00688                 if (divstep <= divmax) {
00689                         NUMLIST s1, s2;
00690                         NUMBER ncl1, ncl2;
00691                         divide_all_spheres (spheres, all, s1,s2,(l+r)/2,direction);
00692                         //cout <<"diV ";
00693                         ncl1=partcount(spheres, s1, l,(l+r)/2, lm,rm, divstep+1, divmax, direction,dimension, clusters, firstclno);
00694                         ncl2=partcount(spheres, s2, (l+r)/2,r, lm,rm, divstep+1, divmax, direction,dimension, clusters, ncl1);
00695                         nextclno=combine(spheres, s1,s2,clusters,firstclno,ncl1,ncl2,(l+r)/2,direction);
00696                 }
00697 
00698                 else {
00699                         //cout <<"diM ";
00700                         nextclno=partcount(spheres, all, lm,rm, lm,rm, 1, divmax, direction+1,dimension, clusters, firstclno);
00701                 }
00702         }
00703                 
00704         return nextclno;
00705 }
00706 
00707 
00708 NUMBER divide_d_times_count_and_analyze(sphere* spheres, 
00709                                                                 NUMLIST &all,
00710                                                                 NUMBER N, 
00711                                                                 NUMBER d,
00712                                                                 NUMBER *histogram, 
00713                                                                 NUMBER &biggestcl, 
00714                                                                 REAL &averagecl)
00715 {
00716         cluson *clusters=new cluson[N+1];
00717 
00718         int dimension=getdim( spheres[*all.begin()].c );
00719 
00720         NUMBER nextcluster=partcount(spheres, all, 0, GRIDSIZE, (COORDFLOAT)0, GRIDSIZE, 1, d, 1,dimension, clusters, 1);
00721 
00722         NUMBER biggestcl_no=analyze_clusters (clusters, 1, nextcluster-1,histogram,N,biggestcl,averagecl);
00723 
00724         delete[] clusters;
00725 
00726         return (biggestcl_no);
00727 }
00728 
00729 
00730 
00731 
00732 COUNTER choose_optimal_cuts (int dim, NUMBER N, REAL R){
00733 
00734         REAL rc=give_radius(ff_critical_guessed(N, dim), N, GRIDSIZE, dim);
00735         REAL rs=give_radius(saturating_fillingfactor(dim, N), N, GRIDSIZE, dim);
00736 //      cout <<"rc="<<rc<<"  rs="<<rs<<"    this R="<<R<<endl;
00737         REAL lowest_N=39.0625;
00738         NUMBER Nclose=rounded(lowest_N * rounded(pow(2, 1+rounded(log(N/(2*lowest_N))/log(2)))));
00739         if (Nclose>480000) Nclose=480000;
00740 //      cout <<"N="<<N<<" Nclose="<<Nclose<<endl;
00741 
00742         COUNTER cuts_c=choose_optimal_cuts_ffc(dim, Nclose);
00743         COUNTER cuts_s=choose_optimal_cuts_ffs(dim, Nclose);
00744         if (cuts_s > cuts_c) cuts_s=cuts_c;
00745 
00746         if (dim==1) return cuts_c;  // because then rs==rc
00747         
00748         REAL cuts=cuts_c + (cuts_s-cuts_c)* (R-rc)/(rs-rc);
00749 
00750 //      cout <<"cuts_c="<<cuts_c<<"   cuts_s="<<cuts_s<<"   cuts_R="<<cuts<<"  return "<<endl;
00751         cuts=rounded(cuts);
00752         return (COUNTER)(cuts>0?cuts:0);
00753 }
00754 
00755 void test_cuts_function(){
00756         cout<<"type in dim, N"<<endl;
00757         int dim; COUNTER N;
00758         cin>>dim>>N;
00759         REAL R=0;
00760         while (R!=-1){
00761                 cout <<"\ntype in R (-1 for end)";
00762                 cin>>R;
00763                 cout <<choose_optimal_cuts(dim, N, R);
00764         }
00765 }
00766 
00767 
00768 
00769 
00770 
00771 // the divide-by-c-cuts counters:
00772 // this algo divides the space into smaller cells, 
00773 // if necessary non-square, rectangular
00774 //
00775 // with a total number of cuts in all dimensional directions
00776 // -> cuts = dividings.dim1 + dividings.dim2 + ...+ dividings.dimd
00777 // #cells = 2^cuts 
00778 // advantage: smaller steps 
00779 //       4dim: 8 cuts -> 2^8 = 256 boxes (cuts=2+2+2+2)
00780 //             9 cuts -> 2^9 = 512 boxes (cuts=3+2+2+2)
00781 
00782 // !!! this one is used NOW !!!
00783 
00784 #ifndef TIMEMEASUREMENT
00785 
00786 NUMBER dividecount (sphere* spheres, NUMLIST &all,
00787                                                   COORDFLOAT l, COORDFLOAT r,
00788                                                   COORDFLOAT lm,COORDFLOAT rm,
00789                                                   COUNTER divstep, COUNTER divcounter,
00790                                                   int direction, int dimension,
00791                                                   cluson *clusters, NUMBER firstclno)
00792 {
00793         NUMBER nextclno;
00794 
00795         if (divstep < divcounter/direction ) {
00796                 NUMLIST s1, s2;
00797                 NUMBER ncl1, ncl2;
00798                 divide_all_spheres (spheres, all, s1,s2,(l+r)/2,direction);
00799                 ncl1=dividecount(spheres, s1,                                                                   // RECURSION!
00800                                                           l,(l+r)/2, lm,rm, 
00801                                                           divstep+1, divcounter, 
00802                                                           direction,dimension, 
00803                                                           clusters, firstclno);
00804                 ncl2=dividecount(spheres, s2,                                                                   // RECURSION!
00805                                                           (l+r)/2,r, lm,rm, 
00806                                                           divstep+1, divcounter, 
00807                                                           direction,dimension, 
00808                                                           clusters, ncl1);
00809                 nextclno=combine(spheres, s1,s2,clusters,firstclno,ncl1,ncl2,(l+r)/2,direction);
00810         }
00811 
00812         else {
00813                 if (direction==1) {
00814                                                                 // the core clusterCounter
00815                                                                 // (naive recursion or iteration with full network)
00816                         nextclno=list_to_temp_array_and_find_cluster(spheres, all, firstclno);   
00817                         make_clusterlist_array (spheres, all, clusters);
00818                 }
00819                 else {
00820                         // continue in next-lower direction (divcounter-divstep cuts left to do)
00821                         nextclno=dividecount(spheres, all, 
00822                                                                                 lm,rm, lm,rm, 
00823                                                                                 0, divcounter-divstep, 
00824                                                                                 direction-1,dimension, 
00825                                                                                 clusters, firstclno);
00826                 }
00827         }
00828         return nextclno;
00829 }
00830 
00831 #else // if defined TIMEMEASUREMENT
00832 
00833 class timedividecount{
00834 public:
00835         clock_t cellcount;
00836         clock_t clusterlist;
00837         clock_t divide;
00838         clock_t combine;
00839         clock_t dividerecursion;
00840         timedividecount(){cellcount=0; clusterlist=0; divide=0; combine=0;dividerecursion=0;};
00841 };
00842 
00843 timedividecount tdiv;
00844 
00845 
00846 NUMBER dividecount (sphere* spheres, NUMLIST &all,
00847                                                   COORDFLOAT l, COORDFLOAT r,
00848                                                   COORDFLOAT lm,COORDFLOAT rm,
00849                                                   COUNTER divstep, COUNTER divcounter,
00850                                                   int direction, int dimension,
00851                                                   cluson *clusters, NUMBER firstclno)
00852 {
00853          clock_t ttemp;
00854          ttemp=clock();
00855 
00856         NUMBER nextclno;
00857         if (divstep < divcounter/direction ) {
00858                 NUMLIST s1, s2;
00859                 NUMBER ncl1, ncl2;
00860 
00861                  ttemp=clock();
00862                 divide_all_spheres (spheres, all, s1,s2,(l+r)/2,direction);
00863                  tdiv.divide+=clock()-ttemp;
00864 
00865                 ncl1=dividecount(spheres, s1,                                                                   // RECURSION!
00866                                                           l,(l+r)/2, lm,rm, 
00867                                                           divstep+1, divcounter, 
00868                                                           direction,dimension, 
00869                                                           clusters, firstclno);
00870                 ncl2=dividecount(spheres, s2,                                                                   // RECURSION!
00871                                                           (l+r)/2,r, lm,rm, 
00872                                                           divstep+1, divcounter, 
00873                                                           direction,dimension, 
00874                                                           clusters, ncl1);
00875 
00876                  ttemp=clock();
00877                 nextclno=combine(spheres, s1,s2,clusters,firstclno,ncl1,ncl2,(l+r)/2,direction);
00878                  tdiv.combine+=clock()-ttemp;
00879         }
00880 
00881         else {
00882                 if (direction==1) {
00883                                                                 // the core clusterCounter
00884                                                                 // (naive recursion or iteration with full network)
00885 
00886                          ttemp=clock();
00887                         nextclno=list_to_temp_array_and_find_cluster(spheres, all, firstclno);   
00888                          tdiv.cellcount+=clock()-ttemp;
00889                          ttemp=clock();
00890                         make_clusterlist_array (spheres, all, clusters);
00891                          tdiv.clusterlist+=clock()-ttemp;
00892                 }
00893                 else {
00894                         // continue in next-lower direction (divcounter-divstep cuts left to do)
00895                         nextclno=dividecount(spheres, all, 
00896                                                                                 lm,rm, lm,rm, 
00897                                                                                 0, divcounter-divstep, 
00898                                                                                 direction-1,dimension, 
00899                                                                                 clusters, firstclno);
00900                 }
00901         }
00902         return nextclno;
00903 }
00904 
00905 #endif // defined TIMEMEASUREMENT
00906 
00907 
00908 // This intermediate step returns an array of clusons=spherelist
00909 // used for visualization
00910 NUMBER count_analyze_and_return_clusters(NUMBER c,
00911                                                                                                    sphere* spheres, NUMLIST &all,
00912                                                                                                         cluson *clusters,
00913                                                                                                         NUMBER *histogram, 
00914                                                                                                         NUMBER &biggestcl, REAL &averagecl)
00915 {
00916 //      if (c>=1) {
00917                 int dimension=getdim( spheres[*all.begin()].c );
00918 
00919                 NUMBER nextcluster=dividecount(spheres, all, 
00920                                                                                             0,GRIDSIZE,0,GRIDSIZE, 
00921                                                                                                  0, c, 
00922                                                                                             dimension,dimension, 
00923                                                                                             clusters, 1);
00924 
00925                 erasehisto(histogram,1,all.size());
00926                 NUMBER biggestcl_no;
00927                 NUMBER totalnumber= makehistogram ( clusters,
00928                                                                                                         1,nextcluster-1,
00929                                                                                                         histogram, 
00930                                                                                                         biggestcl_no, 
00931                                                                                                         biggestcl,
00932                                                                                                         averagecl);
00933 
00934         if (totalnumber != (NUMBER)all.size()) {
00935                 errorout("not all the spheres are in clusters!");
00936                 cout << "number of spheres: N="<<all.size();
00937                 cout <<"  counted="<<totalnumber<<endl;
00938                 exit(1);
00939         }
00940         else ; // cout <<"N="<<all.size()<<"  counted="<<totalnumber<<endl;
00941 
00942 //      }
00943 //      else exit(1);
00944 
00945         return (nextcluster-1);   // returns the number of clusters (M0)
00946 
00947 }
00948 
00949 
00950 // the same as count_analyze_and_return_clusters, but throws away the cluson-array
00951 NUMBER divide_by_c_cuts_count_and_analyze(sphere* spheres, NUMLIST &all,
00952                                                                                   NUMBER c,
00953                                                                                   NUMBER *histogram, 
00954                                                                                   NUMBER &biggestcl, 
00955                                                                                   REAL &averagecl)
00956 {
00957         cluson *clusters=new cluson[all.size()+1];
00958    
00959         NUMBER number_of_clusters= count_analyze_and_return_clusters(c,
00960                                                                                                  spheres, all,
00961                                                                                                  clusters, histogram, 
00962                                                                                                  biggestcl, averagecl);
00963 
00964         delete[] clusters;
00965 
00966         return number_of_clusters;
00967 }
00968 
00969 
00970 // this one is used NOW (in find_ffc, into_file8, etc.)
00971 // it returns an array of clusons=spherelists
00972 
00973 #ifndef TIMEMEASUREMENT
00974 
00975 NUMBER divide_count_and_analyze(sphere* spheres, NUMLIST &all,
00976                                                                 NUMBER c,
00977                                                                 cluson *clusters,
00978                                                                 NUMBER &biggestcl, 
00979                                                                 REAL &mean_clsz)
00980 {
00981         NUMBER *histogram=new NUMBER[all.size()+1];                     
00982         if (histogram==NULL) exit_out_of_memory("divide_count_and_analyze(...): NUMBER *histogram");
00983         erasehisto(histogram,1,all.size());
00984    
00985         int dimension=getdim( spheres[*all.begin()].c );
00986 
00987         NUMBER numberof_cl=dividecount(spheres, all, 
00988                                                                         0,GRIDSIZE,(COORDFLOAT)0,GRIDSIZE, 
00989                                                                         0, c, 
00990                                                                         dimension,dimension, 
00991                                                                         clusters, 1);
00992 
00993         NUMBER biggestcl_no;
00994         NUMBER totalnumber= makehistogram ( clusters,
00995                                                                                 1,numberof_cl-1,
00996                                                                                 histogram, 
00997                                                                                 biggestcl_no, 
00998                                                                                 biggestcl,
00999                                                                                 mean_clsz);
01000         if (totalnumber != (NUMBER)all.size()) {
01001                 errorout("not all the spheres are in clusters!");
01002                 cout << "number of spheres: N="<<all.size();
01003                 cout <<"  counted="<<totalnumber<<endl;
01004                 waitanykey();
01005         }
01006         
01007         delete[] histogram;
01008 
01009         return numberof_cl-1;
01010 }
01011 
01012 #else // if TIMEMEASUREMENT wanted
01013 
01014 NUMBER divide_count_and_analyze(sphere* spheres, NUMLIST &all,
01015                                                                 NUMBER c,
01016                                                                 cluson *clusters,
01017                                                                 NUMBER &biggestcl, 
01018                                                                 REAL &mean_clsz)
01019 {
01020         NUMBER *histogram=new NUMBER[all.size()+1];                     
01021         if (histogram==NULL) exit_out_of_memory("divide_count_and_analyze(...): NUMBER *histogram");
01022         erasehisto(histogram,1,all.size());
01023    
01024         int dimension=getdim( spheres[*all.begin()].c );
01025 
01026         clock_t ttemp=clock();
01027         NUMBER numberof_cl=dividecount(spheres, all, 
01028                                                                         0,GRIDSIZE,(COORDFLOAT)0,GRIDSIZE, 
01029                                                                         0, c, 
01030                                                                         dimension,dimension, 
01031                                                                         clusters, 1);
01032         tdiv.dividerecursion+=clock()-ttemp;
01033 
01034         NUMBER biggestcl_no;
01035         NUMBER totalnumber= makehistogram ( clusters,
01036                                                                                 1,numberof_cl-1,
01037                                                                                 histogram, 
01038                                                                                 biggestcl_no, 
01039                                                                                 biggestcl,
01040                                                                                 mean_clsz);
01041         if (totalnumber != (NUMBER)all.size()) {
01042                 errorout("not all the spheres are in clusters!");
01043                 cout << "number of spheres: N="<<all.size();
01044                 cout <<"  counted="<<totalnumber<<endl;
01045                 waitanykey();
01046         }
01047         
01048         delete[] histogram;
01049 
01050         return numberof_cl-1;
01051 }
01052 
01053 #endif // TIMEMEASUREMENT
01054 
01055 
01056 } // end of namespace counters
01057 
01058 




Diploma Thesis Sourcecode Documentation
check out the text and the executable binaries

www.AndreasKrueger.de/thesis/code