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); }
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; }
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(); }