| 35 | } |
| 36 | |
| 37 | Eigen::MatrixXd computeIBpyGivenX(const ClusteringWorkspace& ws, |
| 38 | const hydra::EmbeddingGroup& tasks, |
| 39 | const hydra::EmbeddingDistance& metric, |
| 40 | const PyGivenXConfig& config) { |
| 41 | const auto fmt = hydra::getDefaultFormat(); |
| 42 | |
| 43 | size_t N = ws.size(); |
| 44 | size_t M = tasks.embeddings.size() + 1; |
| 45 | |
| 46 | Eigen::MatrixXd py_x = Eigen::MatrixXd::Ones(M, N) * 1e-12; |
| 47 | Eigen::MatrixXd py_x_temp = Eigen::MatrixXd::Zero(M, N); |
| 48 | py_x_temp.row(0).setConstant(config.score_threshold); |
| 49 | VLOG(15) << "----------------------------------------"; |
| 50 | VLOG(15) << "Computing workspace feature scores"; |
| 51 | VLOG(15) << "----------------------------------------"; |
| 52 | for (auto&& [idx, feature] : ws.features) { |
| 53 | const auto scores = tasks.getScores(metric, feature); |
| 54 | VLOG(15) << "scores @ " << idx << ": " << scores.format(fmt); |
| 55 | py_x_temp.block(1, idx, M - 1, 1) = scores.cast<double>(); |
| 56 | } |
| 57 | VLOG(15) << "----------------------------------------"; |
| 58 | |
| 59 | size_t k = std::min(M, config.top_k); |
| 60 | size_t l = k; |
| 61 | if (config.cumulative) { |
| 62 | l = 1; |
| 63 | } |
| 64 | while (l <= k) { |
| 65 | const auto top_k_inds = findTopKIndicesCols(py_x_temp, l); |
| 66 | for (const auto& idx : top_k_inds) { |
| 67 | py_x(idx.first, idx.second) = |
| 68 | py_x(idx.first, idx.second) + py_x_temp(idx.first, idx.second); |
| 69 | } |
| 70 | l++; |
| 71 | } |
| 72 | |
| 73 | if (config.null_task_preprune) { |
| 74 | // Null task processing |
| 75 | const auto top_inds = findTopKIndicesCols(py_x_temp, 1); |
| 76 | for (const auto& idx : top_inds) { |
| 77 | // Null task corresponds to first row |
| 78 | if (idx.first == 0) { |
| 79 | py_x.block(1, idx.second, M - 1, 1).setConstant(1e-12); |
| 80 | // Essentially 0 (but not 0 to avoid NaN error) |
| 81 | } |
| 82 | } |
| 83 | } |
| 84 | |
| 85 | VLOG(10) << "raw: p(y|x): " << py_x.format(fmt); |
| 86 | const auto scored = py_x.bottomRows(M - 1); |
| 87 | const auto min = scored.rowwise().minCoeff(); |
| 88 | const auto max = scored.rowwise().maxCoeff(); |
| 89 | const auto avg = scored.rowwise().mean(); |
| 90 | VLOG(10) << "score average: " << avg.format(fmt) << ", range: " << min.format(fmt) |
| 91 | << " -> " << max.format(fmt); |
| 92 | |
| 93 | const auto norm_factor = py_x.colwise().sum(); |
| 94 | py_x.array().rowwise() /= norm_factor.array(); |
no test coverage detected