stats: add function for adding two histograms

This patch adds a function to the HistStor class for adding two histograms.
This functionality is required for Ruby.  It also adds support for printing
histograms in a single line.
This commit is contained in:
Nilay Vaish 2014-01-10 16:19:40 -06:00
parent 0387281e2a
commit cfe912a512
3 changed files with 59 additions and 9 deletions

View file

@ -352,6 +352,27 @@ HistStor::grow_up()
bucket_size *= 2; bucket_size *= 2;
} }
void
HistStor::add(HistStor *hs)
{
int b_size = hs->size();
assert(size() == b_size);
assert(min_bucket == hs->min_bucket);
sum += hs->sum;
logs += hs->logs;
squares += hs->squares;
samples += hs->samples;
while(bucket_size > hs->bucket_size)
hs->grow_up();
while(bucket_size < hs->bucket_size)
grow_up();
for (uint32_t i = 0; i < b_size; i++)
cvec[i] += hs->cvec[i];
}
Formula::Formula() Formula::Formula()
{ {
} }

View file

@ -228,12 +228,12 @@ class DataWrap : public InfoAccess
/** /**
* Copy constructor, copies are not allowed. * Copy constructor, copies are not allowed.
*/ */
DataWrap(const DataWrap &stat); DataWrap(const DataWrap &stat) {}
/** /**
* Can't copy stats. * Can't copy stats.
*/ */
void operator=(const DataWrap &); void operator=(const DataWrap &) {}
public: public:
DataWrap() DataWrap()
@ -1502,6 +1502,7 @@ class HistStor
void grow_up(); void grow_up();
void grow_out(); void grow_out();
void grow_convert(); void grow_convert();
void add(HistStor *);
/** /**
* Add a value to the distribution for the given number of times. * Add a value to the distribution for the given number of times.
@ -1840,6 +1841,12 @@ class DistBase : public DataWrap<Derived, DistInfoProxy>
{ {
data()->reset(this->info()); data()->reset(this->info());
} }
/**
* Add the argument distribution to the this distibution.
*/
void add(DistBase &d) { data()->add(d.data()); }
}; };
template <class Stat> template <class Stat>

View file

@ -210,7 +210,7 @@ ScalarPrint::update(Result val, Result total)
void void
ScalarPrint::operator()(ostream &stream, bool oneLine) const ScalarPrint::operator()(ostream &stream, bool oneLine) const
{ {
if ((flags.isSet(nozero) && value == 0.0) || if ((flags.isSet(nozero) && (!oneLine) && value == 0.0) ||
(flags.isSet(nonan) && std::isnan(value))) (flags.isSet(nonan) && std::isnan(value)))
return; return;
@ -312,7 +312,6 @@ VectorPrint::operator()(std::ostream &stream) const
if (!desc.empty()) if (!desc.empty())
ccprintf(stream, " # %s", desc); ccprintf(stream, " # %s", desc);
} }
stream << endl; stream << endl;
} }
} }
@ -325,10 +324,6 @@ VectorPrint::operator()(std::ostream &stream) const
print.value = total; print.value = total;
print(stream); print(stream);
} }
if (flags.isSet(oneline) && ((!flags.isSet(nozero)) || (total != 0))) {
stream << endl;
}
} }
struct DistPrint struct DistPrint
@ -380,6 +375,7 @@ DistPrint::init(const Text *text, const Info &info)
void void
DistPrint::operator()(ostream &stream) const DistPrint::operator()(ostream &stream) const
{ {
if (flags.isSet(nozero) && data.samples == 0) return;
string base = name + separatorString; string base = name + separatorString;
ScalarPrint print; ScalarPrint print;
@ -390,6 +386,20 @@ DistPrint::operator()(ostream &stream) const
print.pdf = NAN; print.pdf = NAN;
print.cdf = NAN; print.cdf = NAN;
if (flags.isSet(oneline)) {
print.name = base + "bucket_size";
print.value = data.bucket_size;
print(stream);
print.name = base + "min_bucket";
print.value = data.min;
print(stream);
print.name = base + "max_bucket";
print.value = data.max;
print(stream);
}
print.name = base + "samples"; print.name = base + "samples";
print.value = data.samples; print.value = data.samples;
print(stream); print(stream);
@ -436,6 +446,10 @@ DistPrint::operator()(ostream &stream) const
print(stream); print(stream);
} }
if (flags.isSet(oneline)) {
ccprintf(stream, "%-40s", name);
}
for (off_type i = 0; i < size; ++i) { for (off_type i = 0; i < size; ++i) {
stringstream namestr; stringstream namestr;
namestr << base; namestr << base;
@ -448,7 +462,15 @@ DistPrint::operator()(ostream &stream) const
print.name = namestr.str(); print.name = namestr.str();
print.update(data.cvec[i], total); print.update(data.cvec[i], total);
print(stream); print(stream, flags.isSet(oneline));
}
if (flags.isSet(oneline)) {
if (descriptions) {
if (!desc.empty())
ccprintf(stream, " # %s", desc);
}
stream << endl;
} }
if (data.type == Dist && data.overflow != NAN) { if (data.type == Dist && data.overflow != NAN) {