00001
00002
00003
00004
00005
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
00031 indri::lang::WeightNode* childWeightNode = dynamic_cast<indri::lang::WeightNode*>( children[i].second );
00032
00033
00034 indri::lang::CombineNode* childCombineNode = dynamic_cast<indri::lang::CombineNode*>( children[i].second );
00035
00036 if( !childWeightNode && !childCombineNode ) {
00037
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
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
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
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