You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
|
#pragma once
|
|
|
|
#include "comdefs.h"
|
|
|
|
|
|
|
|
using michlib::real;
|
|
|
|
|
|
|
|
class BaseData
|
|
|
|
{
|
|
|
|
protected:
|
|
|
|
static constexpr real fillval = 1.0e10;
|
|
|
|
std::vector<real> data;
|
|
|
|
|
|
|
|
BaseData() = default;
|
|
|
|
|
|
|
|
BaseData(size_t n): data(n) {}
|
|
|
|
|
|
|
|
public:
|
|
|
|
const real& V(size_t i) const { return data[i]; }
|
|
|
|
real& V(size_t i) { return data[i]; }
|
|
|
|
|
|
|
|
const real& operator()(size_t i) const { return data[i]; }
|
|
|
|
real& operator()(size_t i) { return data[i]; }
|
|
|
|
|
|
|
|
size_t N() const { return data.size(); }
|
|
|
|
|
|
|
|
static real Fillval() { return fillval; }
|
|
|
|
|
|
|
|
explicit operator bool() const { return N() != 0; }
|
|
|
|
};
|
|
|
|
|
|
|
|
template<class Data> class Averager: public Data
|
|
|
|
{
|
|
|
|
std::vector<size_t> count;
|
|
|
|
|
|
|
|
public:
|
|
|
|
void Add(const Data& d)
|
|
|
|
{
|
|
|
|
if(!d) return;
|
|
|
|
if(!*this)
|
|
|
|
{
|
|
|
|
*static_cast<Data*>(this) = d;
|
|
|
|
count.resize(Data::N());
|
|
|
|
for(size_t i = 0; i < Data::N(); i++) count[i] = (Data::V(i) == Data::Fillval()) ? 0 : 1;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(Data::N() != d.N()) return;
|
|
|
|
for(size_t i = 0; i < Data::N(); i++)
|
|
|
|
if(d(i) != Data::Fillval())
|
|
|
|
{
|
|
|
|
if(Data::V(i) == Data::Fillval())
|
|
|
|
{
|
|
|
|
Data::V(i) = d(i);
|
|
|
|
count[i] = 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Data::V(i) += d(i);
|
|
|
|
count[i]++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Averager& Div()
|
|
|
|
{
|
|
|
|
if(!*this) return *this;
|
|
|
|
for(size_t i = 0; i < Data::N(); i++)
|
|
|
|
if(count[i] != 0) Data::V(i) /= count[i];
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
};
|