| 270 | } |
| 271 | |
| 272 | inline void ValidateNumericalCuts(HistogramCuts const& cuts, bst_feature_t column_idx, |
| 273 | std::vector<WeightedValue> const& sorted_column, |
| 274 | std::size_t num_bins, double max_normalized_rank_error) { |
| 275 | auto ref = AggregateWeightedColumn(sorted_column); |
| 276 | CHECK(!ref.values.empty()); |
| 277 | |
| 278 | auto beg = cuts.Ptrs()[column_idx]; |
| 279 | auto end = cuts.Ptrs()[column_idx + 1]; |
| 280 | auto first_bin = HistogramCuts::NumericBinLowerBound(cuts.Ptrs(), cuts.Values(), column_idx, beg); |
| 281 | EXPECT_TRUE(std::isinf(first_bin)); |
| 282 | EXPECT_LT(first_bin, 0.0f); |
| 283 | EXPECT_GT(cuts.Values()[beg], ref.values.front()); |
| 284 | EXPECT_GE(cuts.Values()[end - 1], ref.values.back()); |
| 285 | |
| 286 | if (ref.values.size() <= num_bins) { |
| 287 | for (std::size_t i = 0; i < ref.values.size(); ++i) { |
| 288 | ASSERT_EQ(cuts.SearchBin(ref.values[i], column_idx), beg + i) |
| 289 | << "feature=" << column_idx << ", value_index=" << i; |
| 290 | } |
| 291 | } else { |
| 292 | auto stats = MeasureCutRankError(cuts, column_idx, ref); |
| 293 | EXPECT_LE(stats.max_normalized_error, max_normalized_rank_error) |
| 294 | << "feature=" << column_idx << ", cut=" << stats.cut_index |
| 295 | << ", normalized_error=" << stats.max_normalized_error |
| 296 | << ", absolute_error=" << stats.max_absolute_error << ", target_rank=" << stats.target_rank |
| 297 | << ", rank_lo=" << stats.rank_lo << ", rank_hi=" << stats.rank_hi |
| 298 | << ", total_weight=" << stats.total_weight |
| 299 | << ", num_interior_cuts=" << stats.num_interior_cuts; |
| 300 | } |
| 301 | } |
| 302 | |
| 303 | inline void ValidateCategoricalCuts(HistogramCuts const& cuts, bst_feature_t column_idx, |
| 304 | std::vector<WeightedValue> const& sorted_column) { |
no test coverage detected