00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "DAPTA.hpp"
00016
00017 #include <cmath>
00018 #include <vector>
00019 #include <algorithm>
00020 #include <functional>
00021 #include <cassert>
00022 #include <cstdlib>
00023
00024 namespace DAPTA {
00025
00026 template <typename V>
00027 std::vector<int> RCBDecomposer<V>::decompose(unsigned numberOfPartitions, unsigned myNumber) {
00028 std::vector<int> myNodes;
00029
00030
00031 RCBTree *head = new RCBTree(this->vertices.begin(), this->vertices.end(), 0);
00032
00033
00034 int maxLevel = (int)std::ceil(std::log((double)numberOfPartitions)/std::log(2.0));
00035
00036
00037 buildRCBTree(head, maxLevel);
00038
00039
00040 std::vector<PointIt> leafDataBegins, leafDataEnds;
00041 leafDataBegins.reserve(numberOfPartitions*2);
00042 leafDataEnds.reserve(numberOfPartitions*2);
00043 collectLeafNodeData(head, leafDataBegins, leafDataEnds);
00044
00045 std::vector<PointIt> collectProcBegins, collectProcEnds;
00046 collectProcBegins.reserve(leafDataBegins.size());
00047 collectProcEnds.reserve(leafDataEnds.size());
00048
00049
00050 unsigned numLeafs = leafDataBegins.size();
00051 unsigned offSet=0;
00052 while (numLeafs!=numberOfPartitions) {
00053 collectProcBegins.push_back(leafDataBegins[offSet]);
00054 collectProcEnds.push_back(leafDataEnds[offSet+1]);
00055 offSet += 2;
00056 --numLeafs;
00057 }
00058
00059
00060 for (unsigned j=offSet; j<leafDataBegins.size(); ++j) {
00061 collectProcBegins.push_back(leafDataBegins[j]);
00062 collectProcEnds.push_back(leafDataEnds[j]);
00063 }
00064
00065 for (unsigned i=0; i<collectProcBegins.size(); ++i) {
00066 if (i!=myNumber) continue;
00067 for (PointIt it = collectProcBegins[i]; it!=collectProcEnds[i]; ++it) {
00068 myNodes.push_back((*it)->globalID);
00069 }
00070 }
00071
00072
00073 delete head;
00074
00075 return myNodes;
00076 }
00077
00078
00079 template <typename V>
00080 int RCBDecomposer<V>::maxBoxInDimension(PointIt begin, PointIt end) {
00081 typename V::CoordType low[V::dimension];
00082 typename V::CoordType upper[V::dimension];
00083
00084 assert(begin!=end);
00085 for (unsigned i=0; i<V::dimension; ++i) {
00086 low[i] = (*begin)->coords.at(i);
00087 upper[i] = low[i];
00088 }
00089
00090 for (PointIt it=begin; it!=end; ++it) {
00091 for (unsigned i=0; i<V::dimension; ++i) {
00092 low[i] = std::min(low[i], (*it)->coords.at(i));
00093 upper[i] = std::max(upper[i], (*it)->coords.at(i));
00094 }
00095 }
00096
00097 typename V::CoordType maxBox = upper[0]-low[0];
00098 unsigned maxDim = 0;
00099 for (unsigned i=1; i<V::dimension; ++i) {
00100 if ((upper[i]-low[i])>maxBox) {
00101 maxBox = upper[i]-low[i];
00102 maxDim = i;
00103 }
00104 }
00105
00106 return maxDim;
00107 }
00108
00109
00110 template <typename V>
00111 void RCBDecomposer<V>::buildRCBTree(RCBTree *tree, const int& maxLevel) {
00112
00113
00114 int partAxis = maxBoxInDimension(tree->_dataBegin, tree->_dataEnd);
00115
00116
00117 std::sort(tree->_dataBegin, tree->_dataEnd, VertexComparison<V>(partAxis));
00118
00119
00120 int size = tree->_dataEnd-tree->_dataBegin;
00121 if (size<1) return;
00122 int middle = size/2;
00123
00124 tree->_childL = new RCBTree(tree->_dataBegin, tree->_dataBegin+middle,
00125 tree->_level+1);
00126 tree->_childR = new RCBTree(tree->_dataBegin+middle, tree->_dataEnd,
00127 tree->_level+1);
00128
00129
00130 if (tree->_childL->_level<maxLevel) {
00131 buildRCBTree(tree->_childL, maxLevel);
00132 buildRCBTree(tree->_childR, maxLevel);
00133 }
00134
00135 return;
00136 }
00137
00138
00139 template <typename V>
00140 void RCBDecomposer<V>::collectLeafNodeData(RCBTree *tree, std::vector<PointIt>& begins,
00141 std::vector<PointIt>& ends) {
00142 if (leaf(tree)) {
00143 assert(tree != NULL);
00144 begins.push_back(tree->_dataBegin);
00145 ends.push_back(tree->_dataEnd);
00146 } else {
00147 collectLeafNodeData(tree->_childL, begins, ends);
00148 collectLeafNodeData(tree->_childR, begins, ends);
00149 }
00150 }
00151
00152 }