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 }