| 321 | } |
| 322 | |
| 323 | void BinMapper::FindBin(double* values, int num_sample_values, size_t total_sample_cnt, |
| 324 | int max_bin, int min_data_in_bin, int min_split_data, BinType bin_type, |
| 325 | bool use_missing, bool zero_as_missing, |
| 326 | const std::vector<double>& forced_upper_bounds) { |
| 327 | int na_cnt = 0; |
| 328 | int tmp_num_sample_values = 0; |
| 329 | for (int i = 0; i < num_sample_values; ++i) { |
| 330 | if (!std::isnan(values[i])) { |
| 331 | values[tmp_num_sample_values++] = values[i]; |
| 332 | } |
| 333 | } |
| 334 | if (!use_missing) { |
| 335 | missing_type_ = MissingType::None; |
| 336 | } else if (zero_as_missing) { |
| 337 | missing_type_ = MissingType::Zero; |
| 338 | } else { |
| 339 | if (tmp_num_sample_values == num_sample_values) { |
| 340 | missing_type_ = MissingType::None; |
| 341 | } else { |
| 342 | missing_type_ = MissingType::NaN; |
| 343 | na_cnt = num_sample_values - tmp_num_sample_values; |
| 344 | } |
| 345 | } |
| 346 | num_sample_values = tmp_num_sample_values; |
| 347 | |
| 348 | bin_type_ = bin_type; |
| 349 | default_bin_ = 0; |
| 350 | int zero_cnt = static_cast<int>(total_sample_cnt - num_sample_values - na_cnt); |
| 351 | // find distinct_values first |
| 352 | std::vector<double> distinct_values; |
| 353 | std::vector<int> counts; |
| 354 | |
| 355 | std::stable_sort(values, values + num_sample_values); |
| 356 | |
| 357 | // push zero in the front |
| 358 | if (num_sample_values == 0 || (values[0] > 0.0f && zero_cnt > 0)) { |
| 359 | distinct_values.push_back(0.0f); |
| 360 | counts.push_back(zero_cnt); |
| 361 | } |
| 362 | |
| 363 | if (num_sample_values > 0) { |
| 364 | distinct_values.push_back(values[0]); |
| 365 | counts.push_back(1); |
| 366 | } |
| 367 | |
| 368 | for (int i = 1; i < num_sample_values; ++i) { |
| 369 | if (!Common::CheckDoubleEqualOrdered(values[i - 1], values[i])) { |
| 370 | if (values[i - 1] < 0.0f && values[i] > 0.0f) { |
| 371 | distinct_values.push_back(0.0f); |
| 372 | counts.push_back(zero_cnt); |
| 373 | } |
| 374 | distinct_values.push_back(values[i]); |
| 375 | counts.push_back(1); |
| 376 | } else { |
| 377 | // use the large value |
| 378 | distinct_values.back() = values[i]; |
| 379 | ++counts.back(); |
| 380 | } |
no test coverage detected