Changeset 18912


Ignore:
Timestamp:
12/03/14 11:37:24 (10 years ago)
Author:
Mathieu Morlighem
Message:

NEW: added covertree nearest neighbor search (to be debugged)

Location:
issm/trunk-jpl/src/c/classes/kriging
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • issm/trunk-jpl/src/c/classes/kriging/Covertree.cpp

    r18845 r18912  
    11#include "../classes.h"
     2//#include <utility>
     3#include <set>
    24
    35        /*Constructors/Destructors*/
    4 Covertree::Covertree(){/*{{{*/
    5         _error_("Constructor not supported");
    6 }
    7 /*}}}*/
    8 Covertree::~Covertree(){/*{{{*/
    9 }
    10 /*}}}*/
     6Covertree::Covertree(const double& maxDist,const std::vector<Observation>& points){
     7        this->base = 2.;
     8        _root=NULL;
     9        _numNodes=0;
     10        _maxLevel=ceilf(log(maxDist)/log(base));
     11        _minLevel=_maxLevel-1;
     12        std::vector<Observation>::const_iterator it;
     13        for(it=points.begin(); it!=points.end(); ++it) {
     14                this->insert(*it);//adds data to the covertree object
     15        }
     16}
     17
     18Covertree::~Covertree(){
     19        if(_root==NULL) return;
     20        //Get all of the root's children (from any level),
     21        //delete the root, repeat for each of the children
     22        std::vector<CoverTreeNode*> nodes;
     23        nodes.push_back(_root);
     24        while(!nodes.empty()) {
     25                CoverTreeNode* byeNode = nodes[0];
     26                nodes.erase(nodes.begin());
     27                std::vector<CoverTreeNode*> children = byeNode->getAllChildren();
     28                nodes.insert(nodes.begin(),children.begin(),children.end());
     29                //std::cout << _numNodes << "\n";
     30                delete byeNode;
     31                //_numNodes--;
     32        }   
     33}
     34
     35std::vector<Covertree::CoverTreeNode*> Covertree::kNearestNodes(const Observation& p, const unsigned int& k) const{
     36        if(_root==NULL) return std::vector<CoverTreeNode*>();
     37        //maxDist is the kth nearest known point to p, and also the farthest
     38        //point from p in the set minNodes defined below.
     39        double maxDist = p.distance(_root->getObservation());
     40        //minNodes stores the k nearest known points to p.
     41        std::set<distNodePair> minNodes;
     42
     43        minNodes.insert(std::make_pair(maxDist,_root));
     44        std::vector<distNodePair> Qj(1,std::make_pair(maxDist,_root));
     45        for(int level = _maxLevel; level>=_minLevel;level--) {
     46                std::vector<distNodePair>::const_iterator it;
     47                int size = Qj.size();
     48                for(int i=0; i<size; i++) {
     49                        std::vector<CoverTreeNode*> children =
     50                          Qj[i].second->getChildren(level);
     51                        std::vector<CoverTreeNode*>::const_iterator it2;
     52                        for(it2=children.begin(); it2!=children.end(); ++it2) {
     53                                double d = p.distance((*it2)->getObservation());
     54                                if(d < maxDist || minNodes.size() < k) {
     55                                        minNodes.insert(std::make_pair(d,*it2));
     56                                        //--minNodes.end() gives us an iterator to the greatest
     57                                        //element of minNodes.
     58                                        if(minNodes.size() > k) minNodes.erase(--minNodes.end());
     59                                        maxDist = (--minNodes.end())->first;
     60                                }
     61                                Qj.push_back(std::make_pair(d,*it2));
     62                        }
     63                }
     64                double sep = maxDist + pow(base, level);
     65                size = Qj.size();
     66                for(int i=0; i<size; i++) {
     67                        if(Qj[i].first > sep) {
     68                                //quickly removes an element from a vector w/o preserving order.
     69                                Qj[i]=Qj.back();
     70                                Qj.pop_back();
     71                                size--; i--;
     72                        }
     73                }
     74        }
     75        std::vector<CoverTreeNode*> kNN;
     76        std::set<distNodePair>::const_iterator it;
     77        for(it=minNodes.begin();it!=minNodes.end();++it) {
     78                kNN.push_back(it->second);
     79        }
     80        return kNN;
     81}
     82bool Covertree::insert_rec(const Observation& p,
     83                        const std::vector<distNodePair>& Qi,
     84                        const int& level)
     85{
     86        std::vector<std::pair<double, CoverTreeNode*> > Qj;
     87        double sep = pow(base,level);
     88        double minDist = 1.e+50;
     89        std::pair<double,CoverTreeNode*> minQiDist(1.e+50,NULL);
     90        std::vector<std::pair<double, CoverTreeNode*> >::const_iterator it;
     91        for(it=Qi.begin(); it!=Qi.end(); ++it) {
     92                if(it->first<minQiDist.first) minQiDist = *it;
     93                if(it->first<minDist) minDist=it->first;
     94                if(it->first<=sep) Qj.push_back(*it);
     95                std::vector<CoverTreeNode*> children = it->second->getChildren(level);
     96                std::vector<CoverTreeNode*>::const_iterator it2;
     97                for(it2=children.begin();it2!=children.end();++it2) {
     98                        double d = p.distance((*it2)->getObservation());
     99                        if(d<minDist) minDist = d;
     100                        if(d<=sep) {
     101                                Qj.push_back(std::make_pair(d,*it2));
     102                        }
     103                }
     104        }
     105        //std::cout << "level: " << level << ", sep: " << sep << ", dist: " << minQDist.first << "\n";
     106        if(minDist > sep) {
     107                return true;
     108        } else {
     109                bool found = insert_rec(p,Qj,level-1);
     110                //distNodePair minQiDist = distance(p,Qi);
     111                if(found && minQiDist.first <= sep) {
     112                        if(level-1<_minLevel) _minLevel=level-1;
     113                        minQiDist.second->addChild(level,
     114                                                new CoverTreeNode(p));
     115                        //std::cout << "parent is ";
     116                        //minQiDist.second->getObservation().print();
     117                        _numNodes++;
     118                        return false;
     119                } else {
     120                        return found;
     121                }
     122        }
     123}
     124
     125void Covertree::remove_rec(const Observation& p,
     126                        std::map<int,std::vector<distNodePair> >& coverSets,
     127                        int level,
     128                        bool& multi)
     129{
     130        std::vector<distNodePair>& Qi = coverSets[level];
     131        std::vector<distNodePair>& Qj = coverSets[level-1];
     132        double minDist = 1.e+50;
     133        CoverTreeNode* minNode = _root;
     134        CoverTreeNode* parent = 0;
     135        double sep = pow(base, level);
     136        std::vector<distNodePair>::const_iterator it;
     137        //set Qj to be all children q of Qi such that p.distance(q)<=sep
     138        //and also keep track of the minimum distance from p to a node in Qj
     139        //note that every node has itself as a child, but the
     140        //getChildren function only returns non-self-children.
     141        for(it=Qi.begin();it!=Qi.end();++it) {
     142                std::vector<CoverTreeNode*> children = it->second->getChildren(level);
     143                double dist = it->first;
     144                if(dist<minDist) {
     145                        minDist = dist;
     146                        minNode = it->second;
     147                }
     148                if(dist <= sep) {
     149                        Qj.push_back(*it);
     150                }
     151                std::vector<CoverTreeNode*>::const_iterator it2;
     152                for(it2=children.begin();it2!=children.end();++it2) {
     153                        dist = p.distance((*it2)->getObservation());
     154                        if(dist<minDist) {
     155                                minDist = dist;
     156                                minNode = *it2;
     157                                if(dist == 0.0) parent = it->second;
     158                        }
     159                        if(dist <= sep) {
     160                                Qj.push_back(std::make_pair(dist,*it2));
     161                        }
     162                }
     163        }
     164        if(level>_minLevel) remove_rec(p,coverSets,level-1,multi);
     165        if(minNode->hasObservation(p)) {
     166                //the multi flag indicates the point we removed is from a
     167                //node containing multiple points, and we have removed it,
     168                //so we don't need to do anything else.
     169                if(multi) return;
     170                if(!minNode->isSingle()) {
     171                        minNode->removeObservation(p);
     172                        multi=true;
     173                        return;
     174                }
     175                if(parent!=NULL) parent->removeChild(level, minNode);
     176                std::vector<CoverTreeNode*> children = minNode->getChildren(level-1);
     177                std::vector<distNodePair>& Q = coverSets[level-1];
     178                if(Q.size()==1 && Q[0].second==minNode) {
     179                        Q.pop_back();
     180                } else {
     181                        for(unsigned int i=0;i<Q.size();i++) {
     182                                if(Q[i].second==minNode) {
     183                                        Q[i]=Q.back();
     184                                        Q.pop_back();
     185                                        break;
     186                                }
     187                        }
     188                }
     189                std::vector<CoverTreeNode*>::const_iterator it;
     190                for(it=children.begin();it!=children.end();++it) {
     191                        int i = level-1;
     192                        Observation q = (*it)->getObservation();
     193                        double minDQ = 1.e+50;
     194                        CoverTreeNode* minDQNode = nullptr;
     195                        double sep = pow(base,i);
     196                        bool br=false;
     197                        while(true) {
     198                                std::vector<distNodePair>&
     199                                  Q = coverSets[i];
     200                                std::vector<distNodePair>::const_iterator it2;
     201                                minDQ = 1.e+50;
     202                                for(it2=Q.begin();it2!=Q.end();++it2) {
     203                                        double d = q.distance(it2->second->getObservation());
     204                                        if(d<minDQ) {
     205                                                minDQ = d;
     206                                                minDQNode = it2->second;
     207                                                if(d <=sep) {
     208                                                        br=true;
     209                                                        break;
     210                                                }
     211                                        }
     212                                }
     213                                minDQ=1.e+50;
     214                                if(br) break;
     215                                Q.push_back(std::make_pair((*it)->distance(p),*it));
     216                                i++;
     217                                sep = pow(base,i);
     218                        }
     219                        //minDQNode->getObservation().print();
     220                        //std::cout << " is level " << i << " parent of ";
     221                        //(*it)->getObservation().print();
     222                        if (minDQNode != nullptr)
     223                         minDQNode->addChild(i,*it);
     224                }
     225                if(parent!=NULL) {
     226                        delete minNode;
     227                        _numNodes--;
     228                }
     229        }
     230}
     231
     232int Covertree::get_numberofobs(){
     233        return _numNodes;
     234}
     235
     236std::pair<double, Covertree::CoverTreeNode*>
     237Covertree::distance(const Observation& p,
     238                        const std::vector<CoverTreeNode*>& Q)
     239{
     240        double minDist = 1.e+50;
     241        CoverTreeNode* minNode;
     242        std::vector<CoverTreeNode*>::const_iterator it;
     243        for(it=Q.begin();it!=Q.end();++it) {
     244                double dist = p.distance((*it)->getObservation());
     245                if(dist < minDist) {
     246                        minDist = dist;
     247                        minNode = *it;
     248                }
     249        }
     250        return std::make_pair(minDist,minNode); 
     251}
     252
     253void Covertree::insert(const Observation& newObservation)
     254{
     255        if(_root==NULL) {
     256                _root = new CoverTreeNode(newObservation);
     257                _numNodes=1;
     258                return;
     259        }
     260        //TODO: this is pretty inefficient, there may be a better way
     261        //to check if the node already exists...
     262        CoverTreeNode* n = kNearestNodes(newObservation,1)[0];
     263        if(newObservation.distance(n->getObservation())==0.0) {
     264                n->addObservation(newObservation);
     265        } else {
     266                //insert_rec acts under the assumption that there are no nodes with
     267                //distance 0 to newObservation in the cover tree (the previous lines check it)
     268                insert_rec(newObservation,
     269                                        std::vector<distNodePair>
     270                                        (1,std::make_pair(_root->distance(newObservation),_root)),
     271                                        _maxLevel);
     272        }
     273}
     274
     275void Covertree::remove(const Observation& p)
     276{
     277        //Most of this function's code is for the special case of removing the root
     278        if(_root==NULL) return;
     279        bool removingRoot=_root->hasObservation(p);
     280        if(removingRoot && !_root->isSingle()) {
     281                _root->removeObservation(p);
     282                return;
     283        }
     284        CoverTreeNode* newRoot=NULL;
     285        if(removingRoot) {
     286                if(_numNodes==1) {
     287                        //removing the last node...
     288                        delete _root;
     289                        _numNodes--;
     290                        _root=NULL;
     291                        return;
     292                } else {
     293                        for(int i=_maxLevel;i>_minLevel;i--) {
     294                                if(!(_root->getChildren(i).empty())) {
     295                                        newRoot = _root->getChildren(i).back();
     296                                        _root->removeChild(i,newRoot);
     297                                        break;
     298                                }
     299                        }
     300                }
     301        }
     302        std::map<int, std::vector<distNodePair> > coverSets;
     303        coverSets[_maxLevel].push_back(std::make_pair(_root->distance(p),_root));
     304        if(removingRoot)
     305         coverSets[_maxLevel].push_back(std::make_pair(newRoot->distance(p),newRoot));
     306        bool multi = false;
     307        remove_rec(p,coverSets,_maxLevel,multi);
     308        if(removingRoot) {
     309                delete _root;
     310                _numNodes--;
     311                _root=newRoot;
     312        }
     313}
     314
     315std::vector<Observation> Covertree::kNearestNeighbors(const Observation& p,
     316                        const unsigned int& k) const
     317{
     318        if(_root==NULL) return std::vector<Observation>();
     319        std::vector<CoverTreeNode*> v = kNearestNodes(p, k);
     320        std::vector<Observation> kNN;
     321        std::vector<CoverTreeNode*>::const_iterator it;
     322        for(it=v.begin();it!=v.end();++it) {
     323                const std::vector<Observation>& p = (*it)->getObservations();
     324                kNN.insert(kNN.end(),p.begin(),p.end());
     325                if(kNN.size() >= k) break;
     326        }
     327        return kNN;
     328}
     329
     330void Covertree::print() const
     331{
     332        int d = _maxLevel-_minLevel+1;
     333        std::vector<CoverTreeNode*> Q;
     334        Q.push_back(_root);
     335        for(int i=0;i<d;i++) {
     336                std::cout << "LEVEL " << _maxLevel-i << "\n";
     337                std::vector<CoverTreeNode*>::const_iterator it;
     338                for(it=Q.begin();it!=Q.end();++it) {
     339                        (*it)->getObservation().print();
     340                        std::vector<CoverTreeNode*>
     341                          children = (*it)->getChildren(_maxLevel-i);
     342                        std::vector<CoverTreeNode*>::const_iterator it2;
     343                        for(it2=children.begin();it2!=children.end();++it2) {
     344                                std::cout << "  ";
     345                                (*it2)->getObservation().print();
     346                        }
     347                }
     348                std::vector<CoverTreeNode*> newQ;
     349                for(it=Q.begin();it!=Q.end();++it) {
     350                        std::vector<CoverTreeNode*>
     351                          children = (*it)->getChildren(_maxLevel-i);
     352                        newQ.insert(newQ.end(),children.begin(),children.end());
     353                }
     354                Q.insert(Q.end(),newQ.begin(),newQ.end());
     355                std::cout << "\n\n";
     356        }
     357}
     358
     359Covertree::CoverTreeNode* Covertree::getRoot() const
     360{
     361        return _root;
     362}
     363
     364Covertree::CoverTreeNode::CoverTreeNode(const Observation& p) {
     365        _observations.push_back(p);
     366}
     367
     368std::vector<Covertree::CoverTreeNode*>
     369Covertree::CoverTreeNode::getChildren(int level) const
     370{
     371        std::map<int,std::vector<CoverTreeNode*> >::const_iterator
     372          it = _childMap.find(level);
     373        if(it!=_childMap.end()) {
     374                return it->second;
     375        }
     376        return std::vector<CoverTreeNode*>();
     377}
     378
     379void Covertree::CoverTreeNode::addChild(int level, CoverTreeNode* p)
     380{
     381        _childMap[level].push_back(p);
     382}
     383
     384void Covertree::CoverTreeNode::removeChild(int level, CoverTreeNode* p)
     385{
     386        std::vector<CoverTreeNode*>& v = _childMap[level];
     387        for(unsigned int i=0;i<v.size();i++) {
     388                if(v[i]==p) {
     389                        v[i]=v.back();
     390                        v.pop_back();
     391                        break;
     392                }
     393        }
     394}
     395
     396void Covertree::CoverTreeNode::addObservation(const Observation& p)
     397{
     398        if(find(_observations.begin(), _observations.end(), p) == _observations.end())
     399         _observations.push_back(p);
     400}
     401
     402void Covertree::CoverTreeNode::removeObservation(const Observation& p)
     403{
     404        std::vector<Observation>::iterator it =
     405          find(_observations.begin(), _observations.end(), p);
     406        if(it != _observations.end())
     407         _observations.erase(it);
     408}
     409
     410double Covertree::CoverTreeNode::distance(const CoverTreeNode& p) const
     411{
     412        return _observations[0].distance(p.getObservation());
     413}
     414
     415bool Covertree::CoverTreeNode::isSingle() const
     416{
     417        return _observations.size() == 1;
     418}
     419
     420bool Covertree::CoverTreeNode::hasObservation(const Observation& p) const
     421{
     422        return find(_observations.begin(), _observations.end(), p) != _observations.end();
     423}
     424
     425const Observation& Covertree::CoverTreeNode::getObservation() const { return _observations[0]; }
     426
     427std::vector<Covertree::CoverTreeNode*>
     428Covertree::CoverTreeNode::getAllChildren() const
     429{
     430        std::vector<CoverTreeNode*> children;
     431        std::map<int,std::vector<CoverTreeNode*> >::const_iterator it;
     432        for(it=_childMap.begin();it!=_childMap.end();++it) {
     433                children.insert(children.end(), it->second.begin(), it->second.end());
     434        }
     435        return children;
     436}
     437
     438bool Covertree::isValidTree() const {
     439        if(_numNodes==0)
     440         return _root==NULL;
     441
     442        std::vector<CoverTreeNode*> nodes;
     443        nodes.push_back(_root);
     444        for(int i=_maxLevel;i>_minLevel;i--) {
     445                double sep = pow(base,i);
     446                std::vector<CoverTreeNode*>::const_iterator it, it2;
     447                //verify separation invariant of cover tree: for each level,
     448                //every point is farther than base^level away
     449                for(it=nodes.begin(); it!=nodes.end(); ++it) {
     450                        for(it2=nodes.begin(); it2!=nodes.end(); ++it2) {
     451                                double dist=(*it)->distance((*it2)->getObservation());
     452                                if(dist<=sep && dist!=0.0) {
     453                                        std::cout << "Level " << i << " Separation invariant failed.\n";
     454                                        return false;
     455                                }
     456                        }
     457                }
     458                std::vector<CoverTreeNode*> allChildren;
     459                for(it=nodes.begin(); it!=nodes.end(); ++it) {       
     460                        std::vector<CoverTreeNode*> children = (*it)->getChildren(i);
     461                        //verify covering tree invariant: the children of node n at level
     462                        //i are no further than base^i away
     463                        for(it2=children.begin(); it2!=children.end(); ++it2) {
     464                                double dist = (*it2)->distance((*it)->getObservation());
     465                                if(dist>sep) {
     466                                        std::cout << "Level" << i << " covering tree invariant failed.n";
     467                                        return false;
     468                                }
     469                        }
     470                        allChildren.insert
     471                          (allChildren.end(),children.begin(),children.end());
     472                }
     473                nodes.insert(nodes.begin(),allChildren.begin(),allChildren.end());
     474        }
     475        return true;
     476}
    11477
    12478        /*Methods*/
  • issm/trunk-jpl/src/c/classes/kriging/Covertree.h

    r18845 r18912  
    33#define _COVERTREE_H
    44
     5#include <map>
    56class Observation;
    67
    78class Covertree{
    89
     10        /**
     11         * Cover tree node. Consists of arbitrarily many points P, as long as
     12         * they have distance 0 to each other. Keeps track of its children.
     13         */
     14        class CoverTreeNode{
     15                private:
     16                        //_childMap[i] is a vector of the node's children at level i
     17                        std::map<int,std::vector<CoverTreeNode*> > _childMap;
     18                        //_observations is all of the points with distance 0 which are not equal.
     19                        std::vector<Observation> _observations;
     20                public:
     21                        CoverTreeNode(const Observation& o);
     22                        /**
     23                         * Returns the children of the node at level i. Note that this means
     24                         * the children exist in cover set i-1, not level i.
     25                         *
     26                         * Does not include the node itself, though technically every node
     27                         * has itself as a child in a cover tree.
     28                         */
     29                        std::vector<CoverTreeNode*> getChildren(int level) const;
     30                        void addChild(int level, CoverTreeNode* p);
     31                        void removeChild(int level, CoverTreeNode* p);
     32                        void addObservation(const Observation& o);
     33                        void removeObservation(const Observation& o);
     34                        const std::vector<Observation>& getObservations() { return _observations; }
     35                        double distance(const CoverTreeNode& p) const;
     36
     37                        bool isSingle() const;
     38                        bool hasObservation(const Observation& o) const;
     39
     40                        const Observation& getObservation() const;
     41
     42                        /**
     43                         * Return every child of the node from any level. This is handy for
     44                         * the destructor.
     45                         */
     46                        std::vector<CoverTreeNode*> getAllChildren() const;
     47          }; // CoverTreeNode class
     48        private:
     49        typedef std::pair<double, CoverTreeNode*> distNodePair;
     50
     51        CoverTreeNode* _root;
     52        unsigned int _numNodes;
     53        int _maxLevel;//base^_maxLevel should be the max distance
     54        //between any 2 points
     55        int _minLevel;//A level beneath which there are no more new nodes.
     56
     57        std::vector<CoverTreeNode*>
     58          kNearestNodes(const Observation& o, const unsigned int& k) const;
     59        /**
     60         * Recursive implementation of the insert algorithm (see paper).
     61         */
     62        bool insert_rec(const Observation& p,
     63                                const std::vector<distNodePair>& Qi,
     64                                const int& level);
     65
     66        /**
     67         * Finds the node in Q with the minimum distance to p. Returns a
     68         * pair consisting of this node and the distance.
     69         */
     70        distNodePair distance(const Observation& p,
     71                                const std::vector<CoverTreeNode*>& Q);
     72
     73
     74        void remove_rec(const Observation& p,
     75                                std::map<int,std::vector<distNodePair> >& coverSets,
     76                                int level,
     77                                bool& multi);
     78
    979        public:
    10                 Covertree();
    11                 ~Covertree();
     80        double base;
    1281
     82        /**
     83         * Constructs a cover tree which begins with all points in points.
     84         *
     85         * maxDist should be the maximum distance that any two points
     86         * can have between each other. IE p.distance(q) < maxDist for all
     87         * p,q that you will ever try to insert. The cover tree may be invalid
     88         * if an inaccurate maxDist is given.
     89         */
     90
     91        Covertree(const double& maxDist,
     92                                const std::vector<Observation>& points=std::vector<Observation>());
     93        ~Covertree();
     94
     95        /**
     96         * Just for testing/debugging. Returns true iff the cover tree satisfies the
     97         * the covering tree invariants (every node in level i is greater than base^i
     98         * distance from every other node, and every node in level i is less than
     99         * or equal to base^i distance from its children). See the cover tree
     100         * papers for details.
     101         */
     102        bool isValidTree() const;
     103
     104        /**
     105         * Insert newPoint into the cover tree. If newPoint is already present,
     106         * (that is, newPoint==p for some p already in the tree), then the tree
     107         * is unchanged. If p.distance(newPoint)==0.0 but newPoint!=p, then
     108         * newPoint WILL be inserted and both points may be returned in k-nearest-
     109         * neighbor searches.
     110         */
     111        void insert(const Observation& newObservation);
     112
     113        /**
     114         * Remove point p from the cover tree. If p is not present in the tree,
     115         * it will remain unchanged. Otherwise, this will remove exactly one
     116         * point q from the tree satisfying p==q.
     117         */
     118        void remove(const Observation& p);
     119
     120        /**
     121         * Returns the k nearest points to p in order (the 0th element of the vector
     122         * is closest to p, 1th is next, etc). It may return greater than k points
     123         * if there is a tie for the kth place.
     124         */
     125        std::vector<Observation> kNearestNeighbors(const Observation& p, const unsigned int& k) const;
     126
     127        int get_numberofobs();
     128
     129        CoverTreeNode* getRoot() const;
     130
     131        /**
     132         * Print the cover tree.
     133         */
     134        void print() const;
    13135};
    14136#endif //_COVERTREE_H
  • issm/trunk-jpl/src/c/classes/kriging/Observation.cpp

    r18237 r18912  
    44
    55#include <stdlib.h>
     6#include <cmath>
     7#include <utility>
    68#include "../classes.h"
    79
     
    2325}
    2426/*}}}*/
     27Observation::Observation(double x_in, double y_in,double value_in){
     28        this->x = x_in;
     29        this->y = y_in;
     30        this->value = value_in;
     31
     32        this->xi     = 0;
     33        this->yi     = 0;
     34        this->index  = 0;
     35        this->weight = 0.;
     36}
    2537Observation::~Observation(){/*{{{*/
    2638        return;
     
    5971}
    6072/*}}}*/
     73
     74/*Covertree*/
     75void Observation::print(void) const{/*{{{*/
     76
     77        _printf_("Observation\n");
     78        _printf_("   x     : " << this->x << "\n");
     79        _printf_("   y     : " << this->y << "\n");
     80        _printf_("   value : " << this->value << "\n");
     81}
     82/*}}}*/
     83double Observation::distance(const Observation& ob) const
     84{
     85        return std::sqrt( (std::pow( (ob.getXY().first - this->x), 2 ) + std::pow((ob.getXY().second - this->y), 2) ));
     86}
     87
     88const std::pair<double, double>& Observation::getXY() const
     89{
     90        return std::make_pair(this->x, this->y);
     91}
     92bool Observation::operator==(const Observation& ob) const
     93{
     94        return (ob.getXY().first == this->x && ob.getXY().second == this->y && ob.value == this->value);
     95}
     96
     97void Observation::WriteXYObs(const Observation& ob, double* px, double* py, double* pobs){
     98    *px   = ob.getXY().first;
     99    *py   = ob.getXY().second;
     100    *pobs = ob.value;
     101}
  • issm/trunk-jpl/src/c/classes/kriging/Observation.h

    r18237 r18912  
    2020                Observation();
    2121                Observation(double x_in,double y_in,int xi_in,int yi_in,int index_in,double value_in);
     22                Observation(double x_in,double y_in,double value_in);
    2223                ~Observation();
    2324
    2425                /*Object virtual functions definitions*/
     26                double  distance(const Observation& ob) const;
     27                const   std::pair<double, double>& getXY() const;
     28
    2529                void    Echo();
     30                void    print() const;
    2631                void    DeepEcho()  {_error_("Not implemented yet"); };
    2732                int     Id()        {_error_("Not implemented yet"); };
    2833                int     ObjectEnum(){_error_("Not implemented yet"); };
     34                bool operator==(const Observation& ob) const;
    2935                Object *copy();
    3036
    3137                /*Management*/
     38                void WriteXYObs(const Observation& ob, double* px, double* py, double* pobs);
    3239                void WriteXYObs(double* px,double* py,double* pobs);
    3340};
  • issm/trunk-jpl/src/c/classes/kriging/Observations.cpp

    r18845 r18912  
    4343        if(n<=0) _error_("No observation found");
    4444
    45         /*Get tree type*/
    46         options->Get(&this->treetype,"treetype",1);
     45        /*Get tree type (FIXME)*/
     46        IssmDouble dtree = 0.;
     47        options->Get(&dtree,"treetype",1.);
     48        this->treetype = reCast<int>(dtree);
    4749        switch(this->treetype){
    4850                case 1:
     
    155157void Observations::InitCovertree(IssmPDouble* observations_list,IssmPDouble* x,IssmPDouble* y,int n,Options* options){/*{{{*/
    156158
    157         _error_("Not supported yet");
    158 
     159    int maxdepth = 10;
     160         _printf0_("Generating covertree with a maximum depth " <<  maxdepth <<"... ");
     161    this->covertree=new Covertree(maxdepth);
     162
     163    for(int i=0;i<n;i++){
     164                 if(i%1000) printf("progress = %g \n",double(i)/double(n)*100.);
     165                 this->covertree->insert(Observation(x[i],y[i],observations_list[i]));
     166    }
     167
     168         _printf0_("done\n");
    159169}
    160170/*}}}*/
     
    227237}/*}}}*/
    228238void Observations::ObservationList(IssmPDouble **px,IssmPDouble **py,IssmPDouble **pobs,int* pnobs,IssmPDouble x_interp,IssmPDouble y_interp,IssmPDouble radius,int maxdata){/*{{{*/
     239
     240        if(this->treetype==2){
     241                this->ObservationList2(px,py,pobs,pnobs,x_interp,y_interp,radius,maxdata);
     242                return;
     243        }
    229244
    230245        /*Output and Intermediaries*/
     
    603618        xDelete<IssmPDouble>(counter);
    604619}/*}}}*/
     620
     621
     622void Observations::ObservationList2(double **px,double **py,double **pobs,int* pnobs,double x_interp,double y_interp,double radius,int maxdata){/*{{{*/
     623   
     624
     625    double *x            = NULL;
     626    double *y            = NULL;
     627    double *obs          = NULL;
     628    Observation observation=Observation(x_interp,y_interp,0.);
     629    std::vector<Observation> kNN;
     630   
     631    /*If radius is not provided or is 0, return all observations*/
     632    if(radius==0.)
     633    {
     634        kNN=(this->covertree->getRoot())->getObservations();
     635    }
     636    else
     637    {
     638        kNN=(this->covertree->kNearestNeighbors(observation, maxdata));
     639                //cout << "kNN's size: " << kNN.size() << endl;
     640               
     641    }
     642       
     643        //kNN is sort from closest to farthest neighbor
     644        //searches for the first neighbor that is out of radius
     645        //deletes and resizes the kNN vector
     646        vector<Observation>::iterator it;
     647        for (it = kNN.begin(); it != kNN.end(); ++it) {
     648                //(*it).print();
     649                //cout << "\n" << (*it).distance(observation) << endl;
     650                if ((*it).distance(observation) > radius) {
     651                        break;
     652                }
     653        }
     654        kNN.erase(it, kNN.end());
     655   
     656        /*Allocate vectors*/
     657        x   = new double[kNN.size()];
     658        y   = new double[kNN.size()];
     659        obs = new double[kNN.size()];
     660
     661        /*Loop over all observations and fill in x, y and obs*/
     662        int i = 0;
     663        for (it = kNN.begin(); it != kNN.end(); ++it) {
     664                (*it).WriteXYObs((*it), &x[i], &y[i], &obs[i]);
     665                i++;
     666        }
     667   
     668    *px=x;
     669    *py=y;
     670    *pobs=obs;
     671        *pnobs = kNN.size();
     672}/*}}}*/
  • issm/trunk-jpl/src/c/classes/kriging/Observations.h

    r18845 r18912  
    4141                void ObservationList(IssmDouble **px,IssmDouble **py,IssmDouble **pobs,int* pnobs);
    4242                void ObservationList(IssmDouble **px,IssmDouble **py,IssmDouble **pobs,int* pnobs,IssmDouble x_interp,IssmDouble y_interp,IssmDouble radius,int maxdata);
     43                void ObservationList2(IssmDouble **px,IssmDouble **py,IssmDouble **pobs,int* pnobs,IssmDouble x_interp,IssmDouble y_interp,IssmDouble radius,int maxdata);
    4344                void QuadtreeColoring(IssmDouble* A,IssmDouble *x,IssmDouble *y,int n);
    4445                void Variomap(IssmDouble* gamma,IssmDouble *x,int n);
Note: See TracChangeset for help on using the changeset viewer.