indii/ml/aux/KDTreeNode.cpp

00001 #include "KDTreeNode.hpp"
00002 
00003 using namespace indii::ml::aux;
00004 
00005 KDTreeNode::KDTreeNode() : lower(NULL), upper(NULL), ownLower(false),
00006     ownUpper(false) {
00007   //
00008 }
00009 
00010 KDTreeNode::KDTreeNode(DiracMixturePdf* p, const unsigned int i,
00011     const unsigned int depth) : PartitionTreeNode(i, depth) {  
00012   /* set bounds */
00013   vector* x = new vector(p->get(i));
00014   setLower(x, true);
00015   setUpper(x, false);
00016 }
00017 
00018 KDTreeNode::KDTreeNode(DiracMixturePdf* p,
00019     const std::vector<unsigned int>& is, const unsigned int depth) :
00020     PartitionTreeNode(is, depth) {    
00021   const unsigned int N = p->getDimensions();
00022   unsigned int i, j;
00023   
00024   if (is.size() > 0) { // mightn't be for DiracMixturePdf::distributedBuild()
00025     vector* lower = new vector(p->get(is[0]));
00026     vector* upper = new vector(p->get(is[0]));
00027   
00028     /* calculate bounds */
00029     for (i = 1; i < is.size(); i++) {
00030       vector& x = p->get(is[i]);
00031       for (j = 0; j < N; j++) {
00032         if (x(j) < (*lower)(j)) {
00033           (*lower)(j) = x(j);
00034         } else if (x(j) > (*upper)(j)) {
00035           (*upper)(j) = x(j);
00036         }
00037       }
00038     }  
00039 
00040     /* set bounds */
00041     setLower(lower, true);
00042     setUpper(upper, true);
00043   } else {
00044     setLower(NULL, false);
00045     setUpper(NULL, false);
00046   }
00047 }
00048 
00049 KDTreeNode::KDTreeNode(KDTreeNode* left, KDTreeNode* right,
00050     const unsigned int depth) : PartitionTreeNode(left, right, depth) {
00051   unsigned int i;
00052 
00053   /* calculate lower bound */
00054   vector* l1 = left->lower;
00055   vector* l2 = right->lower;
00056   vector* lower = NULL;
00057   bool ownLower = false;
00058 
00059   if (l1 == NULL) {
00060     if (l2 == NULL) {
00061       lower = NULL;
00062     } else {
00063       lower = l2;
00064     }
00065   } else if (l2 == NULL) {
00066     lower = l1;
00067   } else {
00068     assert (l1->size() == l2->size());
00069     lower = new vector(*l1);
00070     for (i = 0; i < l2->size(); i++) {
00071       if ((*l2)(i) < (*lower)(i)) {
00072         (*lower)(i) = (*l2)(i);
00073         ownLower = true;
00074       }
00075     }
00076     if (!ownLower) {
00077       /* lower bound same as left child, so just copy pointer */
00078       delete lower;
00079       lower = l1;
00080     }
00081   }
00082   
00083   /* calculate upper bound */
00084   vector* u1 = left->upper;
00085   vector* u2 = right->upper;
00086   vector* upper = NULL;
00087   bool ownUpper = false;
00088 
00089   if (u1 == NULL) {
00090     if (u2 == NULL) {
00091       upper = NULL;
00092     } else {
00093       upper = u2;
00094     }
00095   } else if (u2 == NULL) {
00096     upper = u1;
00097   } else {
00098     assert (u1->size() == u2->size());  
00099     upper = new vector(*u2);
00100     for (i = 0; i < u1->size(); i++) {
00101       if ((*u1)(i) > (*upper)(i)) {
00102         (*upper)(i) = (*u1)(i);
00103         ownUpper = true;
00104       }
00105     }
00106     if (!ownUpper) {
00107       /* upper bound same as right child, so just copy pointer */
00108       delete upper;
00109       upper = u2;
00110     }
00111   }
00112   
00113   /* set bounds */
00114   setLower(lower, ownLower);
00115   setUpper(upper, ownUpper);
00116 }
00117 
00118 KDTreeNode::KDTreeNode(const KDTreeNode& o) : PartitionTreeNode(o) {
00119   KDTreeNode* left;
00120   KDTreeNode* right;
00121   if (getLeft() == NULL) {
00122     left = NULL;
00123   } else {
00124     left = dynamic_cast<KDTreeNode*>(getLeft());
00125   }
00126   if (getRight() == NULL) {
00127     right = NULL;
00128   } else {
00129     right = dynamic_cast<KDTreeNode*>(getRight());
00130   }
00131 
00132   if (o.ownLower) {
00133     lower = new vector(*o.lower);
00134   } else {
00135     if (left->lower != NULL) {
00136       lower = left->lower;
00137     } else {
00138       lower = right->lower;
00139     }
00140   }
00141   if (o.ownUpper) {
00142     upper = new vector(*o.upper);
00143   } else {
00144     if (isLeaf()) {
00145       upper = lower; // see constructor
00146     } else {
00147       if (right->upper != NULL) {
00148   upper = right->upper;
00149       } else {
00150   upper = left->upper;
00151       }
00152     }
00153   }
00154   
00155   ownLower = o.ownLower;
00156   ownUpper = o.ownUpper;
00157 }
00158 
00159 KDTreeNode& KDTreeNode::operator=(const KDTreeNode& o) {
00160   PartitionTreeNode::operator=(o);
00161 
00162   if (ownLower) {
00163     delete lower;
00164     lower = NULL;
00165   }
00166   if (ownUpper) {
00167     delete upper;
00168     upper = NULL;
00169   }
00170 
00171   KDTreeNode* left;
00172   KDTreeNode* right;
00173   if (getLeft() == NULL) {
00174     left = NULL;
00175   } else {
00176     left = dynamic_cast<KDTreeNode*>(getLeft());
00177   }
00178   if (getRight() == NULL) {
00179     right = NULL;
00180   } else {
00181     right = dynamic_cast<KDTreeNode*>(getRight());
00182   }
00183 
00184   if (o.ownLower) {
00185     lower = new vector(*o.lower);
00186   } else {
00187     if (left->lower != NULL) {
00188       lower = left->lower;
00189     } else {
00190       lower = right->lower;
00191     }
00192   }
00193   if (o.ownUpper) {
00194     upper = new vector(*o.upper);
00195   } else {
00196     if (isLeaf()) {
00197       upper = lower; // see constructor
00198     } else {
00199       if (right->upper != NULL) {
00200   upper = right->upper;
00201       } else {
00202   upper = left->upper;
00203       }
00204     }
00205   }
00206   
00207   ownLower = o.ownLower;
00208   ownUpper = o.ownUpper;
00209 
00210   return *this;
00211 }
00212 
00213 KDTreeNode::~KDTreeNode() {
00214   if (ownLower) {
00215     delete lower;
00216     lower = NULL; // in case lower == upper
00217   }
00218   if (ownUpper) {
00219     delete upper;
00220     upper = NULL;
00221   }
00222 }
00223 
00224 PartitionTreeNode* KDTreeNode::clone() const {
00225   return new KDTreeNode(*this);
00226 }
00227 
00228 void KDTreeNode::setLower(vector* lower, const bool own) {
00229   this->lower = lower;
00230   this->ownLower = own;
00231 }
00232 
00233 void KDTreeNode::setUpper(vector* upper, const bool own) {
00234   this->upper = upper;
00235   this->ownUpper = own;
00236 }
00237 
00238 void KDTreeNode::difference(const vector& x, vector& result) const {
00239   /* pre-condition */
00240   assert (x.size() == getLower()->size());
00241   
00242   const unsigned int N = getLower()->size();
00243 
00244   if (isLeaf()) {
00245     noalias(result) = x - *this->getLower();
00246   } else {
00247     const vector& lower = *getLower();
00248     const vector& upper = *getUpper();
00249     unsigned int i;
00250 
00251     for (i = 0; i < N; i++) {
00252       if (x(i) < lower(i)) {
00253         result(i) = lower(i) - x(i);
00254       } else if (x(i) > upper(i)) {
00255         result(i) = x(i) - upper(i);
00256       } else {
00257         result(i) = 0;
00258       }
00259     }
00260   }
00261 }
00262 
00263 void KDTreeNode::difference(const PartitionTreeNode& node, vector& result)
00264     const {
00265   const KDTreeNode& kdNode = static_cast<const KDTreeNode&>(node);
00266   
00267   /* pre-conditions */
00268   assert (kdNode.getLower()->size() == getLower()->size());
00269   assert (kdNode.getLower()->size() == result.size());
00270 
00271   const unsigned int N = getLower()->size();
00272 
00273   if (isLeaf()) {
00274     kdNode.difference(*getLower(), result);
00275   } else {
00276     const vector& lower = *getLower();
00277     const vector& upper = *getUpper();
00278     const vector& olower = *kdNode.getLower();
00279     const vector& oupper = *kdNode.getUpper();
00280     unsigned int i;
00281 
00282     for (i = 0; i < N; i++) {
00283       if (oupper(i) < lower(i)) {
00284         result(i) = lower(i) - oupper(i);
00285       } else if (olower(i) > upper(i)) {
00286         result(i) = olower(i) - upper(i);
00287       } else {
00288         result(i) = 0;
00289       }
00290     }
00291   }  
00292 }
00293 

Generated on Wed Dec 17 15:11:57 2008 for dysii Dynamical Systems Library by  doxygen 1.5.3