SymbolList Grammar::get_actives() {
	SymbolList actives(terminals);
	//std::vector<char> active_vector;
	for( auto &nT : non_terminals ) {
		for( auto rule : production_rules[get_nt_index(nT)] ) {
			if( subset_of(rule, terminals) ) {
				actives.push_back(nT);
				break;
			}
		}
	}
	SymbolList prev_actives;
	do {
		//std::cout << "get_actives do-while\n";
		prev_actives = actives;
		for( auto& nT : non_terminals ) {
			if( contains_char(actives, nT) ) { continue; }
			for( auto rule : production_rules[get_nt_index(nT)] ) {
				if( subset_of(rule, actives) ) {
					actives.push_back(nT);
					break;
				}
			}
		}
	} while( prev_actives != actives );
	return intersection(actives, non_terminals);
}
Esempio n. 2
0
  void operator()(const Scores& scores,
		  Dependency& dependency)
  {
    const size_t sentence_size = dependency.size();
    const int    last_max = sentence_size + 1;
    
    actives.clear();
    actives.resize(dependency.size() + 2, hypothesis_pair_type());
    
    // initialize by axioms...
    for (int pos = 0; pos != last_max; ++ pos)
      actives(pos, pos + 1).second.score = 0.0;
    
    for (int last = 2; last <= last_max; ++ last)
      for (int length = 2; last - length >= 0; ++ length)  {
	const int first = last - length;
	
	hypothesis_pair_type& cell = actives(first, last);
	
	for (int middle = first + 1; middle < last; ++ middle) {
	  const hypothesis_pair_type& left = actives(first, middle);
	  const hypothesis_pair_type& right = actives(middle, last);
	  
	  // left attachment
	  if (last < last_max) {
	    enumerate(cell.first,  left.first,  right.second, last, middle, scores(last, middle));
	    enumerate(cell.first,  left.second, right.first,  last, middle, scores(last, middle));
	    enumerate(cell.second, left.second, right.second, last, middle, scores(last, middle));
	  }
	  
	  // right attachment
	  if (first == 0)
	    enumerate(cell.first, left.second, right.second, first, middle, scores(first, middle));
	  else {
	    enumerate(cell.first,  left.first,  right.second, first, middle, scores(first, middle));
	    enumerate(cell.first,  left.second, right.first,  first, middle, scores(first, middle));
	    enumerate(cell.second, left.second, right.second, first, middle, scores(first, middle));
	  }
	}
      }
    
    const dep_set_type& deps = actives(0, last_max).first.deps;
    
    dep_set_type::const_iterator diter_end = deps.end();
    for (dep_set_type::const_iterator diter = deps.begin(); diter != diter_end; ++ diter)
      dependency[diter->second - 1] = diter->first;
  }
void frank_wolf (double ** dist_mat, double ** yone, double ** zone, double ** wone, double rho, int N, int K) {
    // cout << "within frank_wolf" << endl;
    // STEP ONE: compute gradient mat initially
    vector< set< pair<int, double> > > actives (N, set<pair<int,double> >());
    vector< priority_queue< pair<int,double>, vector< pair<int,double> >, Compare> > pqueues (N, priority_queue< pair<int,double>, vector< pair<int,double> >, Compare> ());
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) {
            double grad =0.5*dist_mat[i][j]+yone[i][j]+rho*(wone[i][j]-zone[i][j]);
            if (wone[i][j] > 1e-10) {
                actives[i].insert(make_pair(j, grad));
            } else {
                pqueues[i].push(make_pair(j, grad));
            }
        }
    }
    // STEP TWO: iteration solve each row
    int k = 0;  // iteration number
    vector<bool> is_global_optimal_reached (N, false);
    set<pair<int,double> >::iterator it;
    // cout << "within frank_wolf: start iteration" << endl;
    while (k < K) {
        // compute new active atom: can be in active set or not
        vector< pair<int, double> > s (N, pair<int,double>());
        vector<bool> isInActives (N, false);
        for (int i = 0; i < N; i++) {
            if (is_global_optimal_reached[i]) continue;
            if (pqueues[i].size() <= 0) continue;
            pair<int,double> tmp_pair = pqueues[i].top();
            s[i].first = tmp_pair.first;
            s[i].second = tmp_pair.second;
            // cout << s[i].first << ":" << s[i].second << endl;
            for (it=actives[i].begin(); it!=actives[i].end(); ++it) {
                // take the minimal of each row
                if (it->second < s[i].second) {
                    isInActives[i] = true;
                    s[i].first = it->first;
                    s[i].second = it->second;
                }
            }
            // compute gamma: inexact or exact
            double gamma; // step size of line search
#ifdef EXACT_LINE_SEARCH
            double sum1=0.0, sum2=0.0, sum3=0.0, sum4=0.0;
            // gamma* = (sum1 + sum2 + sum3) / sum4, where
            // sum1 = 1/2 sum_n sum_k (w - s)_nk * (|| x_n - mu_k ||^2 - r)
            // sum2 = sum_n sum_k y_nk (w - s)_nk
            // sum3 = - rho * sum_n sum_k  (w - z) (w-s)
            // sum4 = sum_n sum_k rho * (s - w)^2
            for (it=actives[i].begin(); it!=actives[i].end(); ++it) {
                double w_minus_s;
                double w_minus_z = wone[i][it->first] - zone[i][it->first];
                if (it->first == s[i].first) {
                    w_minus_s = wone[i][it->first]-1.0;
                } else {
                    w_minus_s = wone[i][it->first];
                }
                sum1 += 0.5 * w_minus_s * (dist_mat[i][it->first] - r);
                sum2 += yone[i][it->first] * w_minus_s;
                sum3 += rho * w_minus_s * w_minus_z;
                sum4 += rho * w_minus_s * w_minus_s;
            }
            if (!isInActives[i]) {
                sum1 += 0.5 * (-1.0) * (dist_mat[i][s[i].first] -r);
                sum2 += yone[i][it->first] * (-1.0);
                sum3 += rho * (-1.0) * (wone[i][s[i].first]-zone[i][s[i].first]);
                sum4 += rho;
            }

            if (fabs(sum4) > 0) {
                gamma = (sum1 + sum2 + sum3) / sum4;
#ifdef EXACT_LINE_SEARCH_DUMP
                cout << "[exact] i=" << i ;
                cout << ",k=" << k;
                cout << ",sum1="<< sum1;
                cout << ",sum2="<< sum2;
                cout << ",sum3="<< sum3;
                cout << ",sum4="<< sum4;
                cout << ",gamma="<< gamma;
                cout << endl;
#endif
                gamma = max(gamma, 0.0);
                gamma = min(gamma, 1.0);

            } else {
                gamma = 0.0;
                is_global_optimal_reached[i] = true;
            }
#else
            gamma = 2.0 / (k+2.0);
#endif
            // update wone
            // for (int i = 0; i < N; i++) {
            for (it=actives[i].begin(); it!=actives[i].end(); ++it) {
                wone[i][it->first] *= (1-gamma);
            }
            wone[i][s[i].first] += gamma;
            // }
            // update new actives
            // for (int i = 0; i < N; i ++) {
            set<pair<int, double> > temp;
            if (!isInActives[i]) {
                actives[i].insert(pqueues[i].top());
                pqueues[i].pop();
            }
            double new_grad;
            for (it=actives[i].begin(); it!=actives[i].end(); ++it) {
                int j = it->first;
                new_grad=0.5*dist_mat[i][j]+yone[i][j]+rho*(wone[i][j]-zone[i][j]);
                temp.insert (make_pair(it->first, new_grad));
            }
            actives[i].swap(temp);
            // cout << "actives[" << i << "]: " << actives[i].size() << endl;
        }
        // cout << "within frank_wolf: next iteration" << endl;
        k ++;
    }
    // compute value of objective function
    double penalty = first_subproblm_obj (dist_mat, yone, zone, wone, rho, N);
    // report the #iter and objective function
    // cout << "[Frank-Wolfe] iteration: " << k << ", first_subpro_obj: " << penalty << endl;
}
Esempio n. 4
0
  void operator()(const Scores& scores,
		  Dependency& dependency)
  {
    const size_t sentence_size = dependency.size();
    const int    last_max = sentence_size + 1;
    
    actives.clear();
    actives.resize(sentence_size + 2, hypothesis_set_type(sentence_size + 2, sentence_size + 2, sentence_size + 2, hypothesis_type()));
    
    // initialize by axioms...
    for (int pos = 0; pos != last_max; ++ pos) {
      // we need to shift + 1 for correct indexing...
      // [h3, j, h3 j, j + 1] where j == pos + 1 and h3 should starts from -1
      
      for (int h3 = -1; h3 != pos; ++ h3)
	actives(pos, pos + 1)(h3 + 1, h3 + 1, pos + 1).score = 0.0;
    }
    
    for (int last = 2; last <= last_max; ++ last)
      for (int length = 2; last - length >= 0; ++ length)  {
	const int first = last - length;
	
	//
	// is it correct???
	// [h1, first, h2 h3, middle] [h3, middle, h4 h5, last]
	//
	// first  <= h3 < middle
	// middle <= h5 < last
	// h3 <= h4 < h5
	// -1 <= h1 < h3 (or first??? given h3 < middle...?)
	// h1 <= h2 < h3
	
	hypothesis_set_type& cells = actives(first, last);
	
	for (int middle = first + 1; middle < last; ++ middle) {
	  const hypothesis_set_type& lefts  = actives(first, middle);
	  const hypothesis_set_type& rights = actives(middle, last);
	  
	  for (int h3 = first; h3 < middle; ++ h3)
	    for (int h5 = middle; h5 < last; ++ h5)
	      for (int h4 = h3; h4 < h5; ++ h4)
		for (int h1 = -1; h1 < first; ++ h1)
		  for (int h2 = h1; h2 < h3; ++ h2) {
		    const hypothesis_type& left  = lefts(h1 + 1, h2 + 1, h3 + 1);
		    const hypothesis_type& right = rights(h3 + 1, h4 + 1, h5 + 1);
		    
		    // [h1, i, h2 h5, j] (la1; h5 -> h4)
		    // left attachment
		    if (h4 > 0)
		      enumerate(cells(h1 + 1, h2 + 1, h5 + 1),  left,  right, h5, h4, scores(h5, h4));
		    
		    // [h1, i, h2 h4, j] (ra1; h4 -> h5)
		    // right attachment
		    if (h4 >= 0)
		      enumerate(cells(h1 + 1, h2 + 1, h4 + 1), left, right, h4, h5, scores(h4, h5));
		    
		    // [h1, i, h4 h5, j] (la2; h5 -> h2)
		    // left attachment
		    if (h2 > 0)
		      enumerate(cells(h1 + 1, h4 + 1, h5 + 1), left, right, h5, h2, scores(h5, h2));
		    
		    // [h1, i, h2 h4, j] (ra2; h2 -> h5)
		    // right attachment
		    if (h2 >= 0)
		      enumerate(cells(h1 + 1, h2 + 1, h4 + 1), left, right, h2, h5, scores(h2, h5));
		  }
	}
      }
    
    const dep_set_type& deps = actives(0, last_max)(-1 + 1, -1 + 1, 0 + 1).deps;
    
    dep_set_type::const_iterator diter_end = deps.end();
    for (dep_set_type::const_iterator diter = deps.begin(); diter != diter_end; ++ diter)
      dependency[diter->second - 1] = diter->first;
  }
    void operator()(const lattice_type& lattice,
		    hypergraph_type& graph)
    {
      graph.clear();
      
      actives.clear();
      actives.resize(lattice.size() + 2, std::make_pair(hypergraph_type::invalid, hypergraph_type::invalid));
      
      // initialize actives by axioms... (terminals)
      
      for (size_t pos = 0; pos != lattice.size(); ++ pos) {
	
	if (lattice[pos].size() != 1)
	  throw std::runtime_error("this is not a sentential lattice!");
	
	// here, we will construct a partial hypergraph...
	lattice_type::arc_set_type::const_iterator aiter_end  = lattice[pos].end();
	for (lattice_type::arc_set_type::const_iterator aiter = lattice[pos].begin(); aiter != aiter_end; ++ aiter) {
	  
	  if (aiter->distance != 1)
	    throw std::runtime_error("this is not a sentential lattice");
	  
	  hypergraph_type::edge_type& edge = graph.add_edge();
	  edge.rule = rule_type::create(rule_type(vocab_type::X, rule_type::symbol_set_type(1, aiter->label)));
	  
	  edge.features = aiter->features;
	  edge.attributes[attr_dependency_pos] = attribute_set_type::int_type(pos + 1);
	  
	  const hypergraph_type::id_type node_id = graph.add_node().id;
	  
	  graph.connect_edge(edge.id, node_id);
	  
	  actives(pos + 1, pos + aiter->distance + 1).first = node_id;
	  actives(pos + 1, pos + aiter->distance + 1).second = node_id;
	  
#if 0
	  {
	    // right attachment
	    hypergraph_type::edge_type& edge = graph.add_edge(&node_id, (&node_id) + 1);
	    edge.rule = rule_reduce1;
	    
	    edge.attributes[attr_dependency_head]      = attribute_set_type::int_type(pos + 1 - 1);
	    edge.attributes[attr_dependency_dependent] = attribute_set_type::int_type(pos + 1);
	    
	    const hypergraph_type::id_type node_id_next = graph.add_node().id;
	    
	    graph.connect_edge(edge.id, node_id_next);
	    
	    actives(pos + 1, pos + aiter->distance + 1).second = node_id_next;
	  }
#endif
	}
      }
      
      hypergraph_type::edge_type::node_set_type tails(2);
      
      const int last_max = lattice.size() + 1;
      for (int last = 2; last <= last_max; ++ last) 
	for (int length = 2; last - length >= 0; ++ length) {
	  const int first = last - length;
	  
	  id_pair_type& cell = actives(first, last);
	  
	  cell.first  = graph.add_node().id;
	  cell.second = graph.add_node().id;
	  
	  for (int middle = first + 1; middle < last; ++ middle) {
	    if (first == 0 && middle == 1) {
	      // since we have [0^0, 1], we need to enumerate only two cases
	      
	      if (last < last_max) {
		tails.front() = actives(first, middle).first;
		tails.back()  = actives(middle, last).first;
		
		hypergraph_type::edge_type& edge = graph.add_edge(tails.begin() + 1, tails.end());
		edge.rule = rule_reduce1;
		edge.attributes[attr_dependency_head]      = attribute_set_type::int_type(last);
		edge.attributes[attr_dependency_dependent] = attribute_set_type::int_type(middle);
		
		graph.connect_edge(edge.id, cell.first);
	      }
	      
	      {
		tails.front() = actives(first, middle).first;
		tails.back()  = actives(middle, last).second;
		
		hypergraph_type::edge_type& edge = graph.add_edge(tails.begin() + 1, tails.end());
		edge.rule = rule_reduce1;
		edge.attributes[attr_dependency_head]      = attribute_set_type::int_type(first);
		edge.attributes[attr_dependency_dependent] = attribute_set_type::int_type(middle);
		
		graph.connect_edge(edge.id, cell.first);
	      }
	    } else {
	      // we need to enumerate 4 cases
	      if (last < last_max) {
		{
		  tails.front() = actives(first, middle).first;
		  tails.back()  = actives(middle, last).first;
		  
		  // left attachment
		  hypergraph_type::edge_type& edge = graph.add_edge(tails.begin(), tails.end());
		  edge.rule = rule_reduce2;
		  edge.attributes[attr_dependency_head]      = attribute_set_type::int_type(last);
		  edge.attributes[attr_dependency_dependent] = attribute_set_type::int_type(middle);
		  
		  graph.connect_edge(edge.id, cell.first);
		}

		{
		  tails.front() = actives(first, middle).second;
		  tails.back()  = actives(middle, last).first;
		  
		  // left attachment
		  hypergraph_type::edge_type& edge = graph.add_edge(tails.begin(), tails.end());
		  edge.rule = rule_reduce2;
		  edge.attributes[attr_dependency_head]      = attribute_set_type::int_type(last);
		  edge.attributes[attr_dependency_dependent] = attribute_set_type::int_type(middle);
		  
		  graph.connect_edge(edge.id, cell.second);
		}
	      }
	      
	      {
		tails.front() = actives(first, middle).first;
		tails.back()  = actives(middle, last).second;

		// right attachment
		hypergraph_type::edge_type& edge = graph.add_edge(tails.begin(), tails.end());
		edge.rule = rule_reduce2;
		edge.attributes[attr_dependency_head]      = attribute_set_type::int_type(first);
		edge.attributes[attr_dependency_dependent] = attribute_set_type::int_type(middle);
		
		graph.connect_edge(edge.id, cell.first);
	      }
	      
	      {
		tails.front() = actives(first, middle).second;
		tails.back()  = actives(middle, last).second;
		
		// right attachment
		hypergraph_type::edge_type& edge = graph.add_edge(tails.begin(), tails.end());
		edge.rule = rule_reduce2;
		edge.attributes[attr_dependency_head]      = attribute_set_type::int_type(first);
		edge.attributes[attr_dependency_dependent] = attribute_set_type::int_type(middle);
		
		graph.connect_edge(edge.id, cell.second);
	      }
	    }
	  }
	}
      
      // final...
      graph.goal = actives(0, last_max).first;
      graph.topologically_sort();
    }