Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

WeightFoldingCopier.hpp

Go to the documentation of this file.
00001 
00002 //
00003 // WeightFoldingCopier
00004 //
00005 // 17 September 2004 -- tds
00006 //
00007 
00008 #ifndef INDRI_WEIGHTFOLDINGCOPIER_HPP
00009 #define INDRI_WEIGHTFOLDINGCOPIER_HPP
00010 
00011 class WeightFoldingCopier : public indri::lang::Copier {
00012 private:
00013   std::vector<indri::lang::Node*> _nodes;
00014 
00015 public:
00016   ~WeightFoldingCopier() {
00017     delete_vector_contents( _nodes );
00018   }
00019 
00020   indri::lang::Node* defaultAfter( indri::lang::Node* old, indri::lang::Node* newNode ) {
00021     _nodes.push_back( newNode );
00022     return newNode;
00023   }
00024 
00025   indri::lang::Node* after( indri::lang::WeightNode* oldWeightNode, indri::lang::WeightNode* newWeightNode ) {
00026     indri::lang::WeightNode* newerWeightNode = new indri::lang::WeightNode();
00027     const std::vector< std::pair<double, indri::lang::ScoredExtentNode*> >& children = newWeightNode->getChildren();
00028     
00029     for( size_t i=0; i<children.size(); i++ ) {
00030       // is this a weight node?
00031       indri::lang::WeightNode* childWeightNode = dynamic_cast<indri::lang::WeightNode*>( children[i].second );
00032 
00033       // is this a combine node?
00034       indri::lang::CombineNode* childCombineNode = dynamic_cast<indri::lang::CombineNode*>( children[i].second );
00035 
00036       if( !childWeightNode && !childCombineNode ) {
00037         // child is not a weight node, so just add it directly
00038         newerWeightNode->addChild( children[i].first, children[i].second );
00039       } else if( childCombineNode ) {
00040         const std::vector< indri::lang::ScoredExtentNode* >& grandkids = childCombineNode->getChildren();
00041         double kidWeight = children[i].first / double(grandkids.size());
00042         
00043         for( size_t j=0; j<grandkids.size(); j++ ) {
00044           newerWeightNode->addChild( kidWeight, grandkids[j] );
00045         }
00046       } else {
00047         // child _is_ a weight node, so we're going to fold all its children up to this level
00048         const std::vector< std::pair<double, indri::lang::ScoredExtentNode*> >& grandkids = childWeightNode->getChildren();
00049         double parentWeight = children[i].first;
00050         double normalizer = 0.0;
00051 
00052         // need to normalize all weights to sum to 1
00053         for( size_t j=0; j<grandkids.size(); j++ ) {
00054           normalizer += grandkids[j].first;
00055         }
00056     
00057         for( size_t j=0; j<grandkids.size(); j++ ) {
00058           // have to normalize the weight by including the parent weight as well
00059           newerWeightNode->addChild( parentWeight * grandkids[j].first / normalizer,
00060                                      grandkids[j].second );
00061         }
00062       }
00063     }
00064 
00065     newerWeightNode->setNodeName( newWeightNode->nodeName() );
00066     delete newWeightNode;
00067     _nodes.push_back( newerWeightNode );
00068 
00069     return newerWeightNode;
00070   }
00071 };
00072 
00073 #endif // INDRI_WEIGHTFOLDINGCOPIER_HPP
00074 

Generated on Wed Nov 3 12:59:07 2004 for Lemur Toolkit by doxygen1.2.18