8 #ifndef SIG_UTIL_HISTGRAM_HPP
9 #define SIG_UTIL_HISTGRAM_HPP
11 #include "../sigutil.hpp"
52 template <
class T,
size_t Bin>
58 std::array<uint, Bin + 2> count_;
62 void print_base_(std::ostream& ofs)
const
66 auto IntDigit = [](
double v){
return static_cast<int>(std::log10(v) + 1); };
68 auto FirstZero = [](
double v){
70 if (
equal(v, 0))
return keta;
71 while (static_cast<int>(v * std::pow(10, keta)) == 0) ++keta;
75 auto Space = [](
int num){
77 for (
int i = 0; i < num; ++i) space.append(
" ");
81 auto Precision = [](
double v)
84 double dv = v - int(v);
87 if (
equal(dv, 0) || keta >= 15)
break;
96 int const rketa = IntDigit(max_);
97 int const disp_precision =
typename std::conditional<std::is_integral<T>::value, std::true_type, std::false_type>::type{}
99 : IntDigit(delta_) > 1
101 : FirstZero(delta_) +1;
102 int const keta =
std::max(rketa,
std::min((
int) Precision(delta_), disp_precision) + 2);
103 int const ctketa = log10(*std::max_element(count_.begin(), count_.end())) + 1;
104 T
const dbar = num_ < 100 ? 1.0 : num_*0.01;
111 ofs <<
"\n-- Histgram --\n";
112 for (uint i = 0; i < Bin + 2; ++i){
113 auto low = delta_*(i - 1) + min_;
114 auto high = delta_*i + min_;
116 if (i == 0) ofs << std::fixed << std::setprecision(disp_precision) <<
"\n[-∞" << Space(keta - 2) <<
"," << std::setw(keta + 1) << high <<
")" <<
":" << std::setw(ctketa) << count_[i] <<
" ";
117 else if (i == Bin + 1) ofs << std::fixed << std::setprecision(disp_precision) <<
"\n[" << std::setw(keta + 1) << low <<
",+∞" << Space(keta - 2) <<
")" <<
":" << std::setw(ctketa) << count_[i] <<
" ";
118 else ofs << std::fixed << std::setprecision(disp_precision) <<
"\n[" << std::setw(keta + 1) << low <<
"," << std::setw(keta + 1) << high <<
")" <<
":" << std::setw(ctketa) << count_[i] <<
" ";
120 for (uint j = 1; dbar*j <= count_[i]; ++j) ofs <<
"|";
122 ofs << std::resetiosflags(std::ios_base::floatfield) <<
"\n\n";
131 Histgram(T
min, T
max) : min_(min), max_(max), delta_(((double) max - min) / Bin), num_(0)
134 std::cout <<
"error: max - min = " << delta_ << std::endl;
137 for (
auto& ct : count_) ct = 0;
143 for (uint i = 0; i < Bin + 1; ++i){
144 if (value < delta_*i + min_){
153 template <class C, typename std::enable_if<impl::container_traits<C>::exist>::type*& =
enabler>
155 for (
auto const& e : values)
count(e);
166 std::array<uint, Bin> tmp;
167 for (uint i = 0; i < Bin; ++i) tmp[i] = count_[i + 1];
177 auto get_count(uint bin)
const ->Maybe<std::tuple<uint, int, int>>
180 ? Just<std::tuple<uint, int, int>>(std::make_tuple(count_[bin + 1], delta_*bin + min_, delta_*(bin + 1) + min_))
181 :
Nothing(std::make_tuple(static_cast<uint>(0u), 0, 0));
185 void print()
const{ print_base_(std::cout); }
188 void print(FilepassString
const& file_pass)
const
190 std::ofstream ofs(file_pass);
auto get_count() const -> std::array< uint, Bin >
頻度を取得
void print() const
標準出力へ出力
bool is_over_range() const
bin外の要素が存在したか
auto get_count(uint bin) const -> Maybe< std::tuple< uint, int, int >>
bin番目(0 ~ Bin-1)の頻度を取得
Histgram(T min, T max)
コンストラクタ
auto Nothing() -> typename impl::SameIf< T, void, typename boost::none_t, Maybe< T >>::type
値コンストラクタ
bool equal(T1 &&v1, T2 &&v2)
数値の簡易等値比較(厳密な計算でない場合の使用を想定)
void count(C const &values)
void count(T value)
要素をbinに振り分けてカウント
void print(FilepassString const &file_pass) const
ファイルへ出力