logprob_type logprob_buffer(Iterator first, Iterator last, void* buffer) const { matrix_type input(reinterpret_cast<parameter_type*>(buffer), dimension_embedding_ * (order_ - 1), 1); if (last - first < order_) { size_type i = 0; for (/**/; i < order_ - (last - first); ++ i) input.block(dimension_embedding_ * i, 0, dimension_embedding_, 1) = embedding_input_().col(id_eps_); for (/**/; first != last - 1; ++ first, ++ i) input.block(dimension_embedding_ * i, 0, dimension_embedding_, 1) = embedding_input_().col(*first); } else { size_type i = 0; for (/**/; first != last - 1; ++ first, ++ i) input.block(dimension_embedding_ * i, 0, dimension_embedding_, 1) = embedding_input_().col(*first); } if (normalize_) { matrix_type hidden(reinterpret_cast<parameter_type*>(buffer) + dimension_embedding_ * (order_ - 1), dimension_embedding_, 1); hidden = (Wh_() * (Wc_() * input + bc_()).array().unaryExpr(hinge()).matrix() + bh_()).array().unaryExpr(hinge()); double logsum = - std::numeric_limits<double>::infinity(); double logprob = 0.0; const word_type word = *(last - 1); for (id_type id = 0; id != embedding_size_; ++ id) if (id != id_bos_ && id != id_eps_) { const double lp = (embedding_output_().col(id).block(0, 0, dimension_embedding_, 1).transpose() * hidden + embedding_output_().col(id).block(dimension_embedding_, 0, 1, 1))(0, 0); logsum = utils::mathop::logsum(logsum, lp); if (id == word.id()) logprob = lp; } return logprob - logsum; } else return (embedding_output_().col(*(last - 1)).block(0, 0, dimension_embedding_, 1).transpose() * (Wh_() * (Wc_() * input + bc_()).array().unaryExpr(hinge()).matrix() + bh_()).array().unaryExpr(hinge()).matrix() + embedding_output_().col(*(last - 1)).block(dimension_embedding_, 0, 1, 1))(0, 0); }
std::list<Vec3f> Mesher::get_contour() { // Find all of the singular edges in this fan // (edges that aren't shared between multiple triangles). std::set<std::array<float, 6>> valid_edges; for (auto itr=voxel_start; itr != voxel_end; ++itr) { if (valid_edges.count(itr->ba_())) valid_edges.erase(itr->ba_()); else valid_edges.insert(itr->ab_()); if (valid_edges.count(itr->cb_())) valid_edges.erase(itr->cb_()); else valid_edges.insert(itr->bc_()); if (valid_edges.count(itr->ac_())) valid_edges.erase(itr->ac_()); else valid_edges.insert(itr->ca_()); } std::set<std::array<float, 3>> in_fan; std::list<Vec3f> contour = {voxel_start->a}; in_fan.insert(voxel_start->a_()); in_fan.insert(voxel_start->b_()); in_fan.insert(voxel_start->c_()); fan_start = voxel_start; voxel_start++; while (contour.size() == 1 || contour.front() != contour.back()) { std::list<Triangle>::iterator itr; for (itr=fan_start; itr != voxel_end; ++itr) { const auto& t = *itr; if (contour.back() == t.a && valid_edges.count(t.ab_())) { contour.push_back(t.b); break; } if (contour.back() == t.b && valid_edges.count(t.bc_())) { contour.push_back(t.c); break; } if (contour.back() == t.c && valid_edges.count(t.ca_())) { contour.push_back(t.a); break; } } // If we broke out of the loop (meaning itr is pointing to a relevant // triangle which should be moved forward to before voxel_start), then // push the list around and update iterators appropriately. if (itr != voxel_end) { in_fan.insert(itr->a_()); in_fan.insert(itr->b_()); in_fan.insert(itr->c_()); if (itr == voxel_start) { voxel_start++; } else if (itr != fan_start) { const Triangle t = *itr; triangles.insert(voxel_start, t); itr = triangles.erase(itr); itr--; } } } // Special case to catch triangles that are part of a particular fan but // don't have any edges in the contour (which can happen!). for (auto itr=voxel_start; itr != voxel_end; ++itr) { if (in_fan.count(itr->a_()) && in_fan.count(itr->b_()) && in_fan.count(itr->c_())) { if (itr == voxel_start) { voxel_start++; } else if (itr != fan_start) { const Triangle t = *itr; triangles.insert(voxel_start, t); itr = triangles.erase(itr); itr--; } } } // Remove the last point of the contour, since it's a closed loop. contour.pop_back(); return contour; }