AMROC Main     Blockstructured Adaptive Mesh Refinement in object-oriented C++


Main Page   Class Hierarchy   Compound List   File List  

Cluster3.C

Go to the documentation of this file.
00001 
00007 #include "DAGH.h"
00008 #include "values.h"
00009 
00010 #ifdef __KCC
00011  template class GridData(2)<short>;
00012  template class GridData(3)<short>;
00013  template class GridData(1)<int>;
00014 #endif
00015 
00016 #define MAXPOINTS                    (10000)
00017 #define MAXPOINTS2               (100000000)
00018 #define MIN_EFFICIENCY                 (0.4)
00019 #define MINOFF                           (4)
00020 #define ITHRES                           (2)
00021 
00028 void Cluster_Prune(GridData(1)<int> &sig, int& pl, int& pu, int bw) {
00029   BeginFastIndex1(sig, sig.bbox(), sig.data(), int);
00030   pl = sig.bbox().lower(0);
00031   pu = sig.bbox().upper(0);
00032   if (pu - pl < bw) {
00033     return;
00034   }
00035   while (FastIndex1(sig,pl) == 0 && pl < sig.bbox().upper(0)) 
00036     pl += sig.bbox().stepsize(0);
00037   while (FastIndex1(sig,pu) == 0 && pu > sig.bbox().lower(0)) 
00038     pu -= sig.bbox().stepsize(0);
00039   if (pu+sig.bbox().stepsize(0)-pl < bw) {
00040     int diff = bw - (pu+sig.bbox().stepsize(0)-pl);
00041     int addl, addu;
00042     int udist = sig.bbox().upper(0) - pu;
00043     int ldist = pl - sig.bbox().lower(0);
00044 
00045     addl = ((diff/sig.bbox().stepsize(0))/2) * sig.bbox().stepsize(0);
00046     addu = diff - addl;
00047     if (addu > udist) {
00048       addu = udist;
00049       addl = diff - addu;
00050     }
00051     if (addl > ldist) {
00052       addl = ldist;
00053       addu = diff - addu;
00054     }
00055 
00056     pu += addu;
00057     pl -= addl;
00058   }
00059   EndFastIndex1(sig);
00060 }
00061 
00069 void Cluster_Slice(GridData(1)<int> &sig, int& slice, int& str, int bw) {
00070   int i, l, u, s, t, a;         // ctr, low, up, step, str, answer
00071   l = sig.bbox().lower(0);
00072   u = sig.bbox().upper(0);
00073   s = sig.bbox().stepsize(0);
00074 
00075   /* Since this box is already pruned, we don't want to split it if
00076      it is less than 2 the min width */
00077   if (u+s-l < 2*bw) {
00078     str   = -1;
00079     slice = -1;
00080     return;
00081   }
00082 
00083   GridData(1)<int> lap(l,u,s);
00084 
00085   BeginFastIndex1(sig, sig.bbox(), sig.data(), int);
00086   BeginFastIndex1(lap, lap.bbox(), lap.data(), int);
00087 
00088   t = -1;
00089   a = -1;
00090   
00091   /* Look for a zero near the center */
00092   for (i=l+bw-s;i<=u-bw;i+=s) {
00093     if (FastIndex1(sig,i) == 0) {
00094       int di = (i-l < u-i ? i-l : u-i);
00095       if (di > t) {
00096         a = i;
00097         t = di;
00098       }
00099     }
00100   }
00101   if (a != -1) {
00102     slice = a;
00103     str = 2*MAXPOINTS2+t;
00104     return;
00105   }
00106 
00107   /* Evaluate the laplacian etc */
00108   int malap = 0;
00109   for (i=l+s; i<=u-s; i+=s) {
00110     lap(i) = FastIndex1(sig,i+s) + FastIndex1(sig,i-s) - 2*FastIndex1(sig,i);
00111     int alap = (FastIndex1(lap,i)>0 ? FastIndex1(lap,i) : -FastIndex1(lap,i));
00112     if (alap > malap) malap = alap;
00113   }
00114 
00115   t = -1;
00116   a = -1;
00117 
00118   /* And find the strongest second derivative */
00119   int tts = -1;
00120   if (malap > 0) {
00121     int ms = Max(MINOFF*s,bw);
00122     for (i=l+ms-s; i<=u-ms; i+=s)
00123       if (FastIndex1(lap,i-s)*FastIndex1(lap,i) < 0) {  
00124         int ts = ((FastIndex1(lap,i-s)-FastIndex1(lap,i))>0 ? 
00125                   FastIndex1(lap,i-s)-FastIndex1(lap,i) : 
00126                   -(FastIndex1(lap,i-s)-FastIndex1(lap,i)));
00127         int di = (i-l < u-i ? i-l : u-i);
00128         if (ts==tts && di>t) {
00129           a = i;
00130           t = di;
00131         }
00132         if (ts>tts) {
00133           tts = ts;
00134           a = i;
00135           t = di;
00136         }
00137       }
00138     if (a!=-1 && tts>=ITHRES) 
00139       t = MAXPOINTS2+tts*MAXPOINTS+t;
00140   }
00141 
00142   /* Use bisection if no slice has been found */
00143   if (a==-1 || tts<ITHRES) {
00144     t = (sig.size()/2)*s-s;
00145     a = l+t;
00146   }
00147   EndFastIndex1(sig);
00148   EndFastIndex1(lap);
00149 
00150   slice = a;
00151   str = t;
00152 }
00153 
00166 void Cluster3R(GridData(3)<short> &flag, 
00167                const BBox& flagbbox,
00168                double Efficiency,
00169                int MinWidth,
00170                int MaxWidth,
00171                BBoxList &recurseOnThis) {
00172   BBoxList result, tmpresult;
00173   int l[3], u[3], s[3];
00174   int i;
00175   for (i=0;i<3;i++) s[i] = flagbbox.stepsize(i);
00176   if (MaxWidth<2*MinWidth) MaxWidth=MAXINT;
00177 
00178   //cout << "Clustering " << flagbbox <<"\n";
00179   //cout.flush();
00180 
00181   /* Declare and fill in Signature Planes in each direction */
00182   Array(1)<int> i_sig(flagbbox.lower(0), 
00183                       flagbbox.upper(0),
00184                       flagbbox.stepsize(0));
00185   Array(1)<int> j_sig(flagbbox.lower(1), 
00186                       flagbbox.upper(1), 
00187                       flagbbox.stepsize(1));
00188   Array(1)<int> k_sig(flagbbox.lower(2), 
00189                       flagbbox.upper(2),
00190                       flagbbox.stepsize(2));
00191   i_sig = 0;
00192   j_sig = 0;
00193   k_sig = 0;
00194   BeginFastIndex3(flag, flag.bbox(), flag.data(), short);
00195   BeginFastIndex1(i_sig, i_sig.bbox(), i_sig.data(), int);
00196   BeginFastIndex1(j_sig, j_sig.bbox(), j_sig.data(), int);
00197   BeginFastIndex1(k_sig, k_sig.bbox(), k_sig.data(), int);
00198 
00199   int flagged = 0;
00200   for_3(ii, jj, kk, flagbbox, flagbbox.stepsize())
00201     if (FastIndex3(flag,ii,jj,kk)>0) {
00202       FastIndex1(i_sig,ii)++;
00203       FastIndex1(j_sig,jj)++;
00204       FastIndex1(k_sig,kk)++;
00205       flagged++;
00206     }
00207   end_for;
00208 
00209   /* Check for pruning */
00210   int ipl, ipu, jpl, jpu, kpl, kpu;
00211   Cluster_Prune(i_sig,ipl,ipu,MinWidth*s[0]);
00212   Cluster_Prune(j_sig,jpl,jpu,MinWidth*s[1]);
00213   Cluster_Prune(k_sig,kpl,kpu,MinWidth*s[2]);
00214 
00215   Coords pl(3,ipl,jpl,kpl);
00216   Coords pu(3,ipu,jpu,kpu);
00217 
00218   if (! ((pl == flagbbox.lower()) &&
00219          (pu == flagbbox.upper()))) {
00220     Coords ps = Coords(3,s);
00221     BBox newB(pl,pu,ps);
00222     // cout <<"  PRUNE :" << newB <<"\n";
00223     // cout.flush();
00224     /* Check my efficiency! */
00225     flagged = 0;
00226     for_3(ii, jj, kk, newB, newB.stepsize())
00227       if (FastIndex3(flag,ii,jj,kk)>0) flagged++;
00228     end_for
00229     if (((double)flagged / (double)newB.size()) >= Efficiency &&
00230         Max(Max(newB.extents(0),newB.extents(1)),newB.extents(2)) <= MaxWidth) {
00231       recurseOnThis.add(newB);
00232       return;
00233     } else {
00234       Cluster3R(flag,newB,Efficiency,MinWidth,MaxWidth,recurseOnThis);
00235       return;
00236     }
00237   }
00238   
00239   /* Find the slice positions */
00240   int istr=-1,   jstr=-1,   kstr=-1;
00241   int islice=-1, jslice=-1, kslice=-1;
00242   Cluster_Slice(i_sig,islice,istr,MinWidth*s[0]);
00243   Cluster_Slice(j_sig,jslice,jstr,MinWidth*s[1]);
00244   Cluster_Slice(k_sig,kslice,kstr,MinWidth*s[2]);
00245 
00246   // cout << "SLICE:"<<islice<<" "<<jslice<<" "<<kslice<<"\n";
00247   // cout << "STR  :"<<istr<<" "<<jstr<<" "<<kstr<<"\n";
00248   // cout.flush();
00249 
00250   /* Don't split small grids. */
00251   /* Bisectioning down to the minimum can occur, if a grid does not have any   */
00252   /* zero signature and the strength of its laplacian is lower than ITHRES. */
00253   /* We accept this grid, if its efficiency is greater than MIN_EFFICIENCY. */
00254   if ((islice+jslice+kslice==-3) ||
00255       (istr<MAXPOINTS2 && jstr<MAXPOINTS2 && kstr<MAXPOINTS2 &&
00256        (double)flagged/(double)flagbbox.size()>MIN_EFFICIENCY &&
00257        Max(Max(flagbbox.extents(0),flagbbox.extents(1)),flagbbox.extents(2)) 
00258        <= MaxWidth)) {
00259     // cout << "RETURNING " << flagbbox << endl << flush;
00260     recurseOnThis.add(flagbbox);
00261     return;
00262   }
00263 
00264   /* Split along the line with the biggest strength */
00265   BBox divme = flagbbox;
00266   if (istr > jstr && istr > kstr) {
00267     l[0] = divme.lower(0); l[1]= divme.lower(1); l[2] = divme.lower(2);
00268     u[0] = islice; u[1]= divme.upper(1); u[2] = divme.upper(2);
00269     tmpresult.add(BBox(3,l,u,s));
00270     l[0] = islice+s[0]; l[1]= divme.lower(1); l[2] = divme.lower(2);
00271     u[0] = divme.upper(0); u[1]= divme.upper(1); u[2] = divme.upper(2);
00272     tmpresult.add(BBox(3,l,u,s));
00273   } else if (jstr > kstr) {
00274     l[0] = divme.lower(0); l[1]= divme.lower(1); l[2] = divme.lower(2);
00275     u[0] = divme.upper(0); u[1]= jslice; u[2] = divme.upper(2);
00276     tmpresult.add(BBox(3,l,u,s));
00277     l[0] = divme.lower(0); l[1]= jslice+s[1]; l[2] = divme.lower(2);
00278     u[0] = divme.upper(0); u[1]= divme.upper(1); u[2] = divme.upper(2);
00279     tmpresult.add(BBox(3,l,u,s));
00280   } else {
00281     l[0] = divme.lower(0); l[1]= divme.lower(1); l[2] = divme.lower(2);
00282     u[0] = divme.upper(0); u[1]= divme.upper(1); u[2] = kslice;
00283     tmpresult.add(BBox(3,l,u,s));
00284     l[0] = divme.lower(0); l[1]= divme.lower(1); l[2] = kslice+s[2];
00285     u[0] = divme.upper(0); u[1]= divme.upper(1); u[2] = divme.upper(2);
00286     tmpresult.add(BBox(3,l,u,s));
00287   }
00288 
00289   /* foreach New bbox */
00290   for (BBox* newB = tmpresult.first(); newB; newB = tmpresult.next()) {
00291     /* Figure out how many points are flagged */
00292     // cout << "Handling "<< *newB <<"\n";
00293     flagged = 0;
00294     double myEff;
00295     for_3(ii, jj, kk, *newB, newB->stepsize())
00296       //cout << "SGF: "<<ii<<" "<<jj<<" "<<kk<<" "<<subgridflag(ii,jj,kk)<<"\n";
00297       //cout.flush();
00298       if (FastIndex3(flag,ii,jj,kk)>0) flagged++;
00299     end_for
00300     myEff = (double)flagged/(double)((*newB).size());
00301     /* Do we have ANY? */
00302     if (flagged) {
00303       // cout <<"Flagged " << flagged << " "<< *newB << "\n";
00304       // cout <<"Efficiency "<<myEff<<" of " << (*newB).size() <<"\n";
00305       // cout.flush();
00306       /* Stopping Condition */
00307       if ((myEff >= Efficiency && 
00308            Max(Max(newB->extents(0),newB->extents(1)),newB->extents(2)) <= MaxWidth) ||
00309           (newB->size() < MinWidth*MinWidth*MinWidth) ||
00310           (islice+jslice+kslice==-3)) {
00311         /* No. This one stays = the list if it contains flagged points */
00312         /* Don't add a degenerate grid! */
00313         int add = 1;
00314         for (BBox *tmp = recurseOnThis.first(); tmp; 
00315              tmp = recurseOnThis.next()) {
00316           if ((*tmp).inside((*newB).lower()) &&
00317               (*tmp).inside((*newB).upper())) add = 0;
00318         }
00319         if (add) {
00320           // cout << "  Adding "<< *newB <<"\n";
00321           // cout.flush();
00322           recurseOnThis.add(*newB);
00323         }
00324       } else {
00325         /* Yes: Recluster this sub-box */
00326         // cout <<"FALL: Flagged " << flagged << " "<< *newB << "\n";
00327         // cout <<"FALL: Efficiency "<<myEff<<" of " << (*newB).size() <<"\n";
00328         // cout.flush();
00329         BBoxList subcluster;
00330         Cluster3R(flag,*newB,Efficiency,MinWidth,MaxWidth,subcluster);
00331         for (BBox *me = subcluster.first(); me; me = subcluster.next()) 
00332           recurseOnThis.add(*me);
00333       }
00334     }
00335   }
00336   EndFastIndex1(i_sig);
00337   EndFastIndex1(j_sig);
00338   EndFastIndex1(k_sig);
00339   EndFastIndex3(flag);
00340   return;
00341 }
00342 
00355 void Cluster2(GridData(2)<short> &flag, 
00356               BBoxList& bblexclude, 
00357               double Efficiency,
00358               int MinWidth,
00359               int MaxWidth,
00360               int BufferWidth,
00361               BBoxList &Result) {
00362   BBoxList Result3D;
00363   GridData(2)<short> newflag(flag.bbox());
00364   BBox flat_3d(3,flag.bbox().lower(0),flag.bbox().lower(1),0,
00365                flag.bbox().upper(0),flag.bbox().upper(1),0,
00366                flag.bbox().stepsize(0),flag.bbox().stepsize(1),1);
00367   GridData(3)<short> clust_this(flat_3d);
00368   int flagged_points = 0;
00369   newflag = 0; clust_this = 0;
00370 
00371   for_2(i, j, flag.bbox(), flag.stepsize())
00372     if (flag(i,j)) {
00373       flagged_points ++;
00374       BBox where(2,i,j,i,j,
00375                  flag.bbox().stepsize(0),
00376                  flag.bbox().stepsize(1));
00377       where.grow(BufferWidth);
00378       newflag.equals(1,where);
00379     }
00380   end_for
00381 
00382   for (BBox *bbex=bblexclude.first();bbex;bbex=bblexclude.next())
00383     newflag.equals(0,*bbex);
00384 
00385   if (flagged_points) {
00386     for_2(i,j,flag.bbox(),flag.stepsize()) 
00387       clust_this(i,j,0) = newflag(i,j);
00388     end_for;
00389     Cluster3R(clust_this, clust_this.bbox(), Efficiency, 
00390               MinWidth, MaxWidth, Result3D);
00391   }
00392 
00393   /*
00394     Make sure that rank is appropriately set for the bboxes in 
00395     Result!!
00396     
00397     Manish Parashar Thu May  9 07:54:32 CDT 1996
00398     */
00399   for (BBox* tmpbb=Result3D.first();tmpbb;tmpbb=Result3D.next()) {
00400     BBox tmp2d(2,tmpbb->lower(),tmpbb->upper(), tmpbb->stepsize());
00401     Result.add(tmp2d);
00402   }
00403 }
00404 
00417 void Cluster3(GridData(3)<short> &flag, 
00418               BBoxList& bblexclude, 
00419               double Efficiency,
00420               int MinWidth,
00421               int MaxWidth,
00422               int BufferWidth,
00423               BBoxList &Result) {
00424   BBoxList tmpresult, result;
00425   GridData(3)<short> newflag(flag.bbox());
00426   int flagged_points = 0;
00427   newflag = 0;
00428   
00429   for_3(i, j, k, flag.bbox(), flag.stepsize())
00430     if (flag(i,j,k)) {
00431       flagged_points ++;
00432       BBox where(3,i,j,k,i,j,k,
00433                  flag.bbox().stepsize(0),
00434                  flag.bbox().stepsize(1),
00435                  flag.bbox().stepsize(2));
00436       where.grow(BufferWidth);
00437       newflag.equals(1,where);
00438     }
00439   end_for
00440 
00441   for (BBox *bbex=bblexclude.first();bbex;bbex=bblexclude.next()) 
00442     newflag.equals(0,*bbex);
00443   
00444   if (flagged_points) {
00445     Cluster3R(newflag, newflag.bbox(), Efficiency, 
00446               MinWidth, MaxWidth, Result);
00447   }
00448 }


Quickstart     Users Guide     Programmers Reference     Installation      Examples     Download



AMROC Main      Home      Contact
last update: 06/01/04