util.h 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. #pragma once
  2. #include "data.h"
  3. #include <util/generic/algorithm.h>
  4. #include <util/generic/hash_set.h>
  5. #include <util/string/vector.h>
  6. namespace NAnalytics {
  7. // Get rid of NaNs and INFs
  8. inline double Finitize(double x, double notFiniteValue = 0.0)
  9. {
  10. return isfinite(x)? x: notFiniteValue;
  11. }
  12. inline void ParseNameAndOpts(const TString& nameAndOpts, TString& name, THashSet<TString>& opts)
  13. {
  14. name.clear();
  15. opts.clear();
  16. bool first = true;
  17. auto vs = SplitString(nameAndOpts, "-");
  18. for (const auto& s : vs) {
  19. if (first) {
  20. name = s;
  21. first = false;
  22. } else {
  23. opts.insert(s);
  24. }
  25. }
  26. }
  27. inline TString ParseName(const TString& nameAndOpts)
  28. {
  29. auto vs = SplitString(nameAndOpts, "-");
  30. if (vs.empty()) {
  31. return TString();
  32. } else {
  33. return vs[0];
  34. }
  35. }
  36. template <class R, class T>
  37. inline R AccumulateIfExist(const TString& name, const TTable& table, R r, T t)
  38. {
  39. ForEach(table.begin(), table.end(), [=,&r] (const TRow& row) {
  40. double value;
  41. if (row.Get(name, value)) {
  42. r = t(r, value);
  43. }
  44. });
  45. return r;
  46. }
  47. inline double MinValue(const TString& nameAndOpts, const TTable& table)
  48. {
  49. TString name;
  50. THashSet<TString> opts;
  51. ParseNameAndOpts(nameAndOpts, name, opts);
  52. bool stack = opts.contains("stack");
  53. if (stack) {
  54. return 0.0;
  55. } else {
  56. auto zero = 0.0;
  57. return AccumulateIfExist(name, table, 1.0 / zero /*+inf*/, [] (double x, double y) {
  58. return Min(x, y);
  59. });
  60. }
  61. }
  62. inline double MaxValue(const TString& nameAndOpts, const TTable& table)
  63. {
  64. TString name;
  65. THashSet<TString> opts;
  66. ParseNameAndOpts(nameAndOpts, name, opts);
  67. bool stack = opts.contains("stack");
  68. if (stack) {
  69. return AccumulateIfExist(name, table, 0.0, [] (double x, double y) {
  70. return x + y;
  71. });
  72. } else {
  73. auto zero = 0.0;
  74. return AccumulateIfExist(name, table, -1.0 / zero /*-inf*/, [] (double x, double y) {
  75. return Max(x, y);
  76. });
  77. }
  78. }
  79. template <class T>
  80. inline void Map(TTable& table, const TString& rname, T t)
  81. {
  82. ForEach(table.begin(), table.end(), [=] (TRow& row) {
  83. row[rname] = t(row);
  84. });
  85. }
  86. inline std::function<bool(const TRow&)> HasNoValueFor(TString name)
  87. {
  88. return [=] (const TRow& row) -> bool {
  89. double value;
  90. return !row.Get(name, value);
  91. };
  92. }
  93. inline std::function<double(const TRow&)> GetValueFor(TString name, double defVal = 0.0)
  94. {
  95. return [=] (const TRow& row) -> double {
  96. double value;
  97. return row.Get(name, value)? value: defVal;
  98. };
  99. }
  100. inline std::function<double(const TRow&)> Const(double defVal = 0.0)
  101. {
  102. return [=] (const TRow&) {
  103. return defVal;
  104. };
  105. }
  106. }