00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 #include "assert.h"
00039 #include <stdlib.h>
00040 #include "tools.hpp"
00041 #include <iostream>
00042 #include "prefix_sum_tools.hpp"
00043 
00044 template <typename T, typename Pr>
00045 int util::extractXDim(const util::RectList<T,Pr>& currentP, int *cuts, std::vector<int> procs[])
00046 {
00047   using namespace std;
00048   using namespace util;
00049   rectangle r;
00050   
00051   int lastCut = -1;
00052   int i = 0;
00053   cuts[0]=1;
00054   
00055   for (vector<rectangle>::const_iterator list_iter1 = currentP.rectangles.begin();list_iter1 != currentP.rectangles.end(); list_iter1++)
00056     {
00057       
00058       r = *list_iter1;
00059       if(r.x_bot_r != lastCut)
00060         {
00061           lastCut=r.x_bot_r;
00062           i++;
00063           cuts[i] = r.x_bot_r;
00064           procs[i-1].push_back(1);
00065         }
00066       procs[i-1].push_back(r.y_bot_r);
00067     }
00068   return i;
00069 }
00070 template <typename T, typename Pr>
00071 int util::extractXDim(const util::RectList<T,Pr>& currentP, int *cuts)
00072 {
00073   using namespace std;
00074   using namespace util;
00075   rectangle r;
00076   
00077   int lastCut = -1;
00078   int i = 0;
00079   cuts[0]=1;
00080   
00081   for (vector<rectangle>::const_iterator list_iter1 = currentP.rectangles.begin();list_iter1 != currentP.rectangles.end(); list_iter1++)
00082     {
00083       
00084       r = *list_iter1;
00085       if(r.x_bot_r != lastCut)
00086         {
00087           lastCut=r.x_bot_r;
00088           i++;
00089           cuts[i] = r.x_bot_r;
00090         }
00091     }
00092   return i;
00093 }
00094 template <typename T, typename Pr>
00095 int util::binarySearch (const Pr& prefixSumArray, int l, int h, T prefixSumBottleneck)
00096 {
00097   int mid, oldMid = -1;
00098 
00099   assert (l <= h);
00100   
00101 
00102   int low=l;
00103   int high=h;
00104 
00105   if (prefixSumBottleneck < prefixSumArray[low]) return -1;
00106 
00107   while (low <= high)
00108     {
00109       mid = (low + high) / 2;
00110       assert (low <= high);
00111       assert (mid >= 0);
00112       assert (mid <= high);
00113       if (prefixSumArray[mid] > prefixSumBottleneck)
00114         {
00115           high = mid - 1;
00116         }
00117       else if (prefixSumArray[mid] < prefixSumBottleneck)
00118         {
00119           oldMid = mid;
00120           low = mid + 1;
00121         }
00122       else
00123         {
00124           low = mid + 1;
00125           oldMid = mid;
00126         }
00127     }
00128 
00129   assert (prefixSumArray[oldMid] <= prefixSumBottleneck);
00130   assert (oldMid == h || prefixSumArray[oldMid+1] > prefixSumBottleneck);
00131 
00132   return oldMid;
00133 }
00134 
00135 
00136 
00137 template <typename T, typename Pr>
00138 int util::binarySearch_interval (const Pr& prefixSumArray, int l, int h, T prefixSumBottleneck, int base)
00139 {
00140   int mid, oldMid = -1;
00141 
00142   int high=h;
00143   int low = l;
00144 
00145   assert (low <= high);
00146   
00147 
00148   if (prefixSumBottleneck < prefixSumArray.interval(base,low)) return -1;
00149 
00150   while (low <= high)
00151     {
00152       mid = (low + high) / 2;
00153       assert (low <= high);
00154       assert (mid >= 0);
00155       assert (mid <= high);
00156       if (prefixSumArray.interval(base,mid) > prefixSumBottleneck)
00157         {
00158           high = mid - 1;
00159         }
00160       else if (prefixSumArray.interval(base,mid) < prefixSumBottleneck)
00161         {
00162           oldMid = mid;
00163           low = mid + 1;
00164         }
00165       else
00166         {
00167           low = mid + 1;
00168           oldMid = mid;
00169         }
00170     }
00171 
00172   assert (prefixSumArray.interval(base, oldMid) <= prefixSumBottleneck);
00173   assert (oldMid == h || prefixSumArray.interval(base, oldMid+1) > prefixSumBottleneck);
00174 
00175 
00176   return oldMid;
00177 }
00178 
00179 
00180 
00181 
00182 template <typename T>
00183 void util::prefixsum(const T *array, T *result, int length)
00184 {
00185   int i;
00186 
00187   assert (array != NULL);
00188   assert (result != NULL);
00189   assert (length >= 0);
00190 
00191   result[0] = 0;
00192   for(i = 1; i < length + 1; i++)
00193     result[i] = result[i - 1] + array[i - 1];
00194 }
00195 
00196 
00197 
00198 template <typename T, typename Pr>
00199 int util::binarySearchLeft(const Pr& prefixSumArray, int low, int high, T prefixSumBottleneck)
00200 {
00201   int mid, oldMid = high;
00202   assert (low <= high);
00203   
00204 
00205   while (low < high)
00206     {
00207       mid = (low + high) / 2;
00208       assert (low <= high);
00209       assert (mid >= 0);
00210       assert (mid <= high);
00211       if (prefixSumArray[mid] > prefixSumBottleneck)
00212         {
00213           oldMid = mid;
00214           high = mid ;
00215         }
00216       else if (prefixSumArray[mid] < prefixSumBottleneck)
00217         {
00218           low = mid + 1;
00219         }
00220       else
00221         return mid;
00222     }
00223   assert (low == high);
00224   return oldMid;
00225 }
00226 
00227 
00228 
00229 
00230 template <typename T, typename Pr, bool row>
00231 util::Aggreg2Dto1D<T,Pr,row>::Aggreg2Dto1D(const Pr& p, int xl, int xh, int yl, int yh)
00232   :pr(p),xlow(xl), xhigh(xh), ylow(yl), yhigh(yh)
00233 {
00234   assert (xl<=xh);
00235   assert (yl<=yh);
00236   if (row)
00237     precomp = pr[xlow-1][ylow-1] - pr[xlow-1][yhigh] ;
00238   else
00239     precomp = pr[xlow-1][ylow-1] - pr[xhigh][ylow-1];
00240   assert(precomp<=0);
00241 }
00242 
00243 template <typename T, typename Pr, bool row>
00244 util::Aggreg2Dto1D<T,Pr,row>::Aggreg2Dto1D(const Aggreg2Dto1D<T,Pr,row>& o)
00245   :pr(o.pr),xlow(o.xlow), xhigh(o.xhigh), ylow(o.ylow), yhigh(o.yhigh), precomp(o.precomp)
00246 {
00247   assert (xlow<=xhigh);
00248   assert (ylow<=yhigh);
00249   
00250   assert (ylow == o.ylow);
00251   assert (yhigh == o.yhigh);
00252 }
00253 
00254 template <typename T, typename Pr, bool row>
00255 const T util::Aggreg2Dto1D<T,Pr,row>::operator[] (int x) const
00256 {
00257   if (row)
00258     {
00259       assert (x>=0);
00260       assert (x <= xhigh-xlow+1);
00261       
00262       assert(precomp + pr[x+xlow-1][yhigh] - pr[x+xlow-1][ylow-1]>=0);
00263       return precomp + pr[x+xlow-1][yhigh] - pr[x+xlow-1][ylow-1];
00264     }
00265   else
00266     {
00267       int y=x;
00268 
00269       assert (y>= 0);
00270       assert (y <= yhigh-ylow+1);
00271       
00272       assert(precomp + pr[xhigh][y+ylow-1] - pr[xlow-1][y+ylow-1]>=0);
00273       return precomp + pr[xhigh][y+ylow-1] - pr[xlow-1][y+ylow-1];
00274     }
00275 }
00276 
00277 template <typename T, typename Pr, bool row>
00278 T util::Aggreg2Dto1D<T,Pr,row>::interval(int i1, int i2) const
00279 {
00280   return (*this)[i2] - (*this)[i1];
00281 }
00282 
00283 
00284 
00285 template <typename T, typename Pr, bool row>
00286 util::AggregMax2Dto1D<T,Pr,row>::AggregMax2Dto1D(const AggregMax2Dto1D& a)
00287     :lineCount(a.lineCount), lineSet(new Aggreg2Dto1D<T,Pr,row>*[lineCount])
00288 {
00289   for (int i=0; i<lineCount; i++)
00290     {
00291       if (a.lineSet[i] != NULL)
00292         lineSet[i] = new Aggreg2Dto1D<T,Pr,row>(*(a.lineSet[i]));
00293       else
00294         lineSet[i] = NULL;
00295     }
00296 }
00297 
00298 template <typename T, typename Pr, bool row>
00299 util::AggregMax2Dto1D<T,Pr,row>::~AggregMax2Dto1D()
00300 {
00301   for (int i=0; i<lineCount; i++)
00302     if (lineSet[i] != NULL)
00303       delete lineSet[i];
00304   delete[] lineSet;
00305 }
00306 
00307 template <typename T, typename Pr, bool row>
00308 util::AggregMax2Dto1D<T,Pr,row>::AggregMax2Dto1D(const Pr& psum, int procY, int *ycuts)
00309   :lineCount(procY), lineSet(new Aggreg2Dto1D<T,Pr,row>*[lineCount])
00310 {
00311   if (row == true)
00312     {
00313       int lastY = 1;
00314       for(int i = 0;i < procY-1; i++)
00315         {
00316           assert (ycuts[i] != 0);
00317           if (lastY <= ycuts[i])
00318             lineSet[i] = new Aggreg2Dto1D<T, Pr, row> (psum, 1, psum.prefixsizeX() - 1, lastY, ycuts[i]);
00319           else
00320             lineSet[i] = NULL;
00321           lastY = ycuts[i] + 1;
00322         }
00323       if (lastY <= psum.prefixsizeY() - 1)
00324         lineSet[procY-1] = new Aggreg2Dto1D<T, Pr, row> (psum, 1, psum.prefixsizeX() - 1, lastY, psum.prefixsizeY() - 1);
00325       else
00326         lineSet[procY-1] = NULL;
00327     }
00328   else 
00329     {
00330       int procX = procY;
00331       int* xcuts = ycuts;
00332       
00333       int lastX = 1;
00334       for(int i = 0;i < procX-1; i++)
00335         {
00336           assert (xcuts[i] != 0);
00337           if (lastX <= xcuts[i])
00338             lineSet[i] = new Aggreg2Dto1D<T, Pr, row> (psum, lastX, xcuts[i], 1, psum.prefixsizeY() - 1 );
00339           else
00340             lineSet[i] = NULL;
00341           lastX = xcuts[i] + 1;
00342         }
00343       if (lastX <= psum.prefixsizeX() - 1)
00344         lineSet[procX-1] = new Aggreg2Dto1D<T, Pr, row> (psum, lastX, psum.prefixsizeX() - 1, 1, psum.prefixsizeY() - 1);
00345       else
00346         lineSet[procX-1] = NULL;
00347     }
00348 }
00349 template <typename T, typename Pr, bool row>
00350 T util::AggregMax2Dto1D<T,Pr,row>::interval(int left, int right) const
00351 {
00352   T maxVal;
00353   int i = 0;
00354   while (lineSet[i] == NULL)
00355     {
00356       assert (i < lineCount);
00357       i++;
00358     }
00359   maxVal = lineSet[i]->interval(left,right);
00360   
00361   for(; i < lineCount; i++)
00362     {
00363       if (lineSet[i] != NULL)
00364         maxVal = std::max(lineSet[i]->interval(left,right), maxVal);
00365     }
00366   return maxVal;
00367 }
00368 template <typename T, typename Pr, bool row>
00369 int util::AggregMax2Dto1D<T,Pr,row>::getLineCount()
00370 {
00371   return lineCount;
00372 }