#ifndef _ScatterDraw_DataSource_h_ #define _ScatterDraw_DataSource_h_ #include namespace Upp { using namespace Eigen; class DataSource : public Pte { public: typedef double (DataSource::*Getdatafun)(int64 id); DataSource() : isParam(false), isExplicit(false) {} virtual ~DataSource() noexcept {magic = 4321234;} virtual double y(int64 ) = 0; virtual double x(int64 ) = 0; virtual double znx(int , int64 ) {NEVER(); return Null;} virtual double zny(int , int64 ) {NEVER(); return Null;} virtual double znFixed(int , int64 ) {NEVER(); return Null;} virtual double y(double ) {NEVER(); return Null;} virtual double x(double ) {NEVER(); return Null;} virtual double f(double ) {NEVER(); return Null;} virtual double f(Vector ) {NEVER(); return Null;} virtual int64 GetCount() const = 0; bool IsEmpty() const {return GetCount() == 0;} virtual int GetznxCount(int64 ) {return 0;} virtual int GetznyCount(int64 ) {return 0;} virtual int GetznFixedCount() {return 0;} bool IsParam() const {return isParam;} bool IsExplicit() const {return isExplicit;} void SetDestructor(Function _OnDestructor) {OnDestructor = _OnDestructor;} double MinY(int64& id) {return Min(&DataSource::y, id);} double MinY() {int64 dummy; return Min(&DataSource::y, dummy);} double MinX(int64& id) {return Min(&DataSource::x, id);} double MinX() {int64 dummy; return Min(&DataSource::x, dummy);} double MaxY(int64& id) {return Max(&DataSource::y, id);} double MaxY() {int64 dummy; return Max(&DataSource::y, dummy);} double MaxX(int64& id) {return Max(&DataSource::x, id);} double MaxX() {int64 dummy; return Max(&DataSource::x, dummy);} double IsSortedY() {return IsSorted(&DataSource::y);} double IsSortedX() {return IsSorted(&DataSource::x);} int64 Closest(double x,double y){return Closest(&DataSource::x, &DataSource::y, x, y);} int64 ClosestY(double d) {return Closest(&DataSource::y, d);} int64 ClosestX(double d) {return Closest(&DataSource::x, d);} double AvgY() {return Avg(&DataSource::y);} double AvgX() {return Avg(&DataSource::x);} double RMSY() {return RMS(&DataSource::y);} double StdDevY(double avg = Null) {return StdDev(&DataSource::y, avg);} double StdDevX(double avg = Null) {return StdDev(&DataSource::x, avg);} double VarianceY(double avg = Null) {return Variance(&DataSource::y, avg);} Vector UpperEnvelopeY(double width) {return UpperEnvelope(&DataSource::y, &DataSource::x, width);} Vector LowerEnvelopeY(double width) {return LowerEnvelope(&DataSource::y, &DataSource::x, width);} Vector CumulativeY() {return Cumulative(&DataSource::y, &DataSource::x);} Vector CumulativeAverageY() {return CumulativeAverage(&DataSource::y, &DataSource::x);} Vector MovingAverageY(double width) {return MovingAverage(&DataSource::y, &DataSource::x, width);} Vector SectorAverageY(double width) {return SectorAverage(&DataSource::y, &DataSource::x, width);} void MaxListY(Vector &id, double width) {MaxList(&DataSource::y, &DataSource::x, id, width);} Pointf MaxSubDataImpY(int64 maxId, int width) {return MaxSubDataImp(&DataSource::y, &DataSource::x, maxId, width);} void ZeroCrossingY(bool ascending, bool descending, Vector &zeros, Vector &ids) { return ZeroCrossing(&DataSource::y, &DataSource::x, ascending, descending, zeros, ids);} double IntegralY() {return Integral(&DataSource::y, &DataSource::x);} double IntegralY(double from, double to, double n) {return Integral(from, to, n);} enum FFT_WINDOW {NO_WINDOW = 0, HAMMING, COS}; enum FFT_TYPE {T_FFT = 0, T_PHASE, T_PSD}; Upp::Vector FFTY(double tSample, bool frequency = false, int type = FFT_TYPE::T_FFT, int window = FFT_WINDOW::HAMMING, int numSub = 1, double overlapping = 0) { return FFT(&DataSource::y, tSample, frequency, type, window, numSub, overlapping);} static int GetFFTWindowCount() {return 3;} static const char *GetFFTWindowStr(int i) { const char *str[] = {"no window", "hamming", "cos"}; if (i < 0 || i >= GetFFTWindowCount()) return 0; return str[i]; } void GetSpectralMomentsY(double from, double to, double n, bool frequency, double &m_1, double &m0, double &m1, double &m2) {GetSpectralMoments(from, to, n, frequency, m_1, m0, m1, m2);} void GetSpectralMomentsY(bool frequency, double &m_1, double &m0, double &m1, double &m2) {GetSpectralMoments(&DataSource::y, &DataSource::x, frequency, m_1, m0, m1, m2);} Vector SortDataY() {return SortData(&DataSource::y);} Vector PercentileY(double rate) {return Percentile(&DataSource::y, rate);} double PercentileValY(double rate) {return PercentileVal(&DataSource::y, rate);} Vector DerivativeY(int orderDer, int orderAcc) {return Derivative(&DataSource::y, &DataSource::x, orderDer, orderAcc);} Vector SavitzkyGolayY(int deg, int size, int der) {return SavitzkyGolay(&DataSource::y, &DataSource::x, deg, size, der);} double Min(Getdatafun getdata, int64& id); double Max(Getdatafun getdata, int64& id); double Avg(Getdatafun getdata); int64 Closest(Getdatafun getdata, double d); int64 Closest(Getdatafun getdataX, Getdatafun getdataY, double x, double y); double IsSorted(Getdatafun getdata); double RMS(Getdatafun getdata); double StdDev(Getdatafun getdata, double avg = Null); double Variance(Getdatafun getdata, double avg = Null); Vector UpperEnvelope(Getdatafun getdataY, Getdatafun getdataX, double width); Vector LowerEnvelope(Getdatafun getdataY, Getdatafun getdataX, double width); Vector Cumulative(Getdatafun getdataY, Getdatafun getdataX); Vector CumulativeAverage(Getdatafun getdataY, Getdatafun getdataX); Vector MovingAverage(Getdatafun getdataY, Getdatafun getdataX, double width); Vector SectorAverage(Getdatafun getdataY, Getdatafun getdataX, double width); void MaxList(Getdatafun getdataY, Getdatafun getdataX, Vector &id, double width); Pointf MaxSubDataImp(Getdatafun getdataY, Getdatafun getdataX, int64 maxId, int64 width); void ZeroCrossing(Getdatafun getdataY, Getdatafun getdataX, bool ascending, bool descending, Vector &zeros, Vector &ids); double Integral(Getdatafun getdataY, Getdatafun getdataX); double Integral(double from, double to, double n); double SinEstim_Amplitude(double avg = Null); bool SinEstim_FreqPhase(double &frequency, double &phase, double avg = Null); Vector FFT(Getdatafun getdata, double tSample, bool frequency = false, int type = FFT_TYPE::T_FFT, int window = FFT_WINDOW::HAMMING, int numSub = 1, double overlapping = 0); void GetSpectralMoments(double from, double to, double n, bool frequency, double &m_1, double &m0, double &m1, double &m2); void GetSpectralMoments(Getdatafun getdataY, Getdatafun getdataX, bool frequency, double &m_1, double &m0, double &m1, double &m2); bool SameX(DataSource &data); Vector SortData(Getdatafun getdata); Vector Percentile(Getdatafun getdata, double rate); double PercentileVal(Getdatafun getdata, double rate); Vector Derivative(Getdatafun getdataY, Getdatafun getdataX, int orderDer, int orderAcc); Vector SavitzkyGolay(Getdatafun getdataY, Getdatafun getdataX, int deg, int size, int der); bool IsMagic() {return magic == 1234321;} // Temporal use, just for testing protected: bool isParam, isExplicit; private: Function OnDestructor; Vector Envelope(Getdatafun getdataY, Getdatafun getdataX, double width, bool (*fun)(double a, double b)); int magic = 1234321; }; class DataXRange : public DataSource { private: DataSource *data; double xHigh, xLow; int count; public: DataXRange() : data(0), count(1000) {} DataXRange(DataSource &_data, double _xLow, double _xHigh) {Init(_data, _xLow, _xHigh);} void Init(DataSource &_data, double _xLow, double _xHigh) { data = &_data; isExplicit = _data.IsExplicit(); isParam = _data.IsParam(); xLow = _xLow; xHigh = _xHigh; count = 1000; } void SetCount(int _count) {count = _count;} void SetXLow(double _xLow) {xLow = _xLow;} void SetXHigh(double _xHigh){xHigh = _xHigh;} bool Check(int64 id) const { double x = data->x(id); if (!IsNull(xHigh) && xHigh < x) return false; if (!IsNull(xLow) && xLow > x) return false; return true; } virtual inline double y(int64 id) { if (isExplicit) return f(xLow + id*(xHigh - xLow)/double(count - 1)); else return Check(id) ? data->y(id) : Null; } virtual inline double x(int64 id) { if (isExplicit) return xLow + id*(xHigh - xLow)/double(count - 1); else return Check(id) ? data->x(id) : Null; } virtual inline double x(double t) { double x = data->x(t); if (!IsNull(xHigh) && xHigh < x) return Null; if (!IsNull(xLow) && xLow > x) return Null; return x; } virtual double f(double x) { if (!IsNull(xHigh) && xHigh < x) return Null; if (!IsNull(xLow) && xLow > x) return Null; return data->f(x); } virtual double MinX() {return xLow;} virtual double MaxX() {return xHigh;} virtual inline int64 GetCount() const { if (isExplicit) return count; return data->GetCount(); } }; class DataReverse : public DataSource { private: DataSource *data; public: DataReverse() : data(0) {} DataReverse(DataSource &_data) {Init(_data);} void Init(DataSource *_data) {Init(*_data);} void Init(DataSource &_data) { ASSERT(!_data.IsExplicit() && !_data.IsParam()); data = &_data; } virtual inline double y(int64 id) {return data->y(GetCount() - id - 1);} virtual inline double x(int64 id) {return data->x(GetCount() - id - 1);} virtual int64 GetCount() const {return data->GetCount();} }; class DataReverseX : public DataSource { private: DataSource *data; public: DataReverseX() : data(0) {} DataReverseX(DataSource &_data) {Init(_data);} void Init(DataSource &_data) { ASSERT(!_data.IsExplicit() && !_data.IsParam()); data = &_data; } virtual inline double y(int64 id) {return data->y(id);} virtual inline double x(int64 id) {return data->x(GetCount() - id - 1);} virtual int64 GetCount() const {return data->GetCount();} }; class DataAppend : public DataSource { protected: DataSource *data1, *data2; public: DataAppend() : data1(0), data2(0) {} DataAppend(DataSource &_data1, DataSource &_data2) {Init(_data1, _data2);} void Init(DataSource &_data1, DataSource &_data2) { ASSERT(!_data1.IsExplicit() && !_data1.IsParam() && !_data2.IsExplicit() && !_data2.IsParam()); data1 = &_data1; data2 = &_data2; } virtual inline double y(int64 id) { int64 count1 = data1->GetCount(); if (id < count1) return data1->y(id); return data2->y(id - count1); } virtual inline double x(int64 id) { int64 count1 = data1->GetCount(); if (id < count1) return data1->x(id); return data2->x(id - count1); } virtual int64 GetCount() const {return data1->GetCount() + data2->GetCount();} }; class DataRange : public DataAppend { public: DataRange() : DataAppend() {} DataRange(DataSource &_data1, DataSource &_data2) {Init(_data1, _data2);} void Init(DataSource &_data1, DataSource &_data2) { ASSERT(!_data1.IsExplicit() && !_data1.IsParam() && !_data2.IsExplicit() && !_data2.IsParam()); data1 = &_data1; rev.Init(_data2); data2 = &rev; } private: DataReverse rev; }; class DataStackedY { public: DataStackedY() : is100(false) {} void Set100(bool _is100) {is100 = _is100;} DataStackedY &Add(DataSource &data) { EachDataStackedY &each = eachData.Add(); each.Init(data, eachData.GetCount() -1, this); return *this; } double Get100Y(int index, int64 id) { double acc = 0; for (int i = 0; i < eachData.GetCount(); ++i) acc += eachData[i].RealY(id); if (acc == 0) return 0; else return 100*eachData[index].RealY(id)/acc; } double GetY(int index, int64 id) { double res = 0; for (int i = 0; i <= index; ++i) { if (is100) res += Get100Y(i, id); else res += eachData[i].RealY(id); } return res; } class EachDataStackedY : public DataSource { public: EachDataStackedY() {} void Init(DataSource &_data, int _index, DataStackedY *_parent) { ASSERT(!_data.IsExplicit() && !_data.IsParam()); this->data = &_data; this->index = _index; this->parent = _parent; } virtual inline double y(int64 id) { return parent->GetY(index, id); } double RealY(int64 id) { return data->y(id); } virtual inline double x(int64 id) { return data->x(id); } virtual int64 GetCount() const { return data->GetCount(); } private: DataSource *data = 0; int index = -1; DataStackedY *parent = 0; }; EachDataStackedY &Get(int id) {return eachData[id];} protected: Array eachData; bool is100; }; class CArray : public DataSource { private: double *yData, *xData, *zData; int64 numData; double x0, deltaX; public: CArray(double *_yData, int _numData, double _x0, double _deltaX) : yData(_yData), numData(_numData), x0(_x0), deltaX(_deltaX) {xData = NULL;} CArray(double *_yData, double *_xData, int _numData) : yData(_yData), xData(_xData), numData(_numData) {zData = NULL; x0 = deltaX = 0;} CArray(double *_yData, double *_xData, double *_zData, int _numData) : yData(_yData), xData(_xData), zData(_zData), numData(_numData) {x0 = deltaX = 0;} virtual inline double y(int64 id) {return yData[ptrdiff_t(id)];} virtual inline double x(int64 id) {return xData ? xData[ptrdiff_t(id)] : id*deltaX + x0;} virtual double znFixed(int n, int64 id); virtual int GetznFixedCount() {return 1;} virtual inline int64 GetCount() const {return numData;} }; template class VectorY : public DataSource { private: Vector *yData; double x0, deltaX; public: VectorY() : yData(0), x0(0), deltaX(0) {} VectorY(Vector &_yData, double _x0, double _deltaX) {Init(_yData, _x0, _deltaX);} void Init(Vector &_yData, double _x0, double _deltaX) { this->yData = &_yData; this->x0 = _x0; this->deltaX = _deltaX; } virtual inline double y(int64 id) {return (*yData)[int(id)];} virtual inline double x(int64 id) {return id*deltaX + x0;} virtual inline int64 GetCount() const {return yData->GetCount();} virtual double MinX() {return x0;} virtual double MaxX() {return x0 + (yData->GetCount() - 1)*deltaX;} virtual double AvgX() {return x0 + ((yData->GetCount() - 1)*deltaX)/2.;} }; template class ArrayY : public DataSource { private: Upp::Array *yData = 0; double x0 = 0, deltaX = 0; public: ArrayY() {} ArrayY(Upp::Array &_yData, double _x0, double _deltaX) {Init(_yData, _x0, _deltaX);} void Init(Upp::Array &_yData, double _x0, double _deltaX) { this->yData = &_yData; this->x0 = _x0; this->deltaX = _deltaX; } virtual inline double y(int64 id) {return (*yData)[ptrdiff_t(id)];} virtual inline double x(int64 id) {return id*deltaX + x0;} virtual inline int64 GetCount() const {return yData->GetCount();} virtual double MinX() {return x0;} virtual double MaxX() {return x0 + yData->GetCount()*deltaX;} virtual double AvgX() {return (x0 + yData->GetCount()*deltaX)/2.;} }; template class VectorVectorY : public DataSource { private: Vector > *data = 0; bool useRows = true; int idx = 0, idy = 1; Vector idsx, idsy, idsFixed; int beginData = 0; int numData = Null; public: VectorVectorY() {} VectorVectorY(Vector > &_data, int _idx, int _idy, Vector &_idsx, Vector &_idsy, Vector &_idsFixed, bool _useRows = true, int _beginData = 0, int _numData = Null) { Init(_data, _idx, _idy, _idsx, _idsy, _idsFixed, _useRows, _beginData, _numData); } void Init(Vector > &_data, int _idx, int _idy, Vector &_idsx, Vector &_idsy, Vector &_idsFixed, bool _useRows = true, int _beginData = 0, int _numData = Null) { this->data = &_data; this->useRows = _useRows; this->idx = _idx; this->idy = _idy; this->idsx = clone(_idsx); this->idsy = clone(_idsy); this->idsFixed = clone(_idsFixed); this->beginData = _beginData; this->numData = _numData; if (IsNull(_numData)) { if (!_useRows) { if (_data.IsEmpty()) this->numData = 0; else this->numData = _data[0].GetCount() - _beginData; } else this->numData = _data.GetCount() - _beginData; } } void Init(Vector > &_data, int _idx, int _idy, bool _useRows = true, int _beginData = 0, int _numData = Null) { static Vector idsVoid; Init(_data, _idx, _idy, idsVoid, idsVoid, idsVoid, _useRows, _beginData, _numData); } virtual inline double y(int64 id) { if (!IsNull(idy) && idy >= 0) { if (useRows) return (*data)[beginData + int(id)][idy]; else return (*data)[idy][beginData + int(id)]; } else { if (GetznyCount(id) == 0) return Null; double ret = 0; for (int i = 0; i < GetznyCount(id); ++i) ret += zny(i, id); return ret/GetznyCount(id); } } virtual inline double x(int64 id) {return useRows ? (*data)[beginData + int(id)][idx] : (*data)[idx][beginData + int(id)];} //virtual inline double xn(int n, int64 id) {return useRows ? (*data)[beginData + int(id)][ids[n]] : (*data)[ids[n]][beginData + int(id)];} virtual inline int64 GetCount() const {return numData;}; virtual double znx(int n, int64 id) {return useRows ? (*data)[beginData + int(id)][idsx[n]] : (*data)[idsx[n]][beginData + int(id)];} virtual double zny(int n, int64 id) const { if (!IsNull(idy) && idy < 0) return useRows ? (*data)[beginData + int(id)][n - idy] : (*data)[n - idy][beginData + int(id)]; return useRows ? (*data)[beginData + int(id)][idsy[n]] : (*data)[idsy[n]][beginData + int(id)]; } virtual double znFixed(int n, int64 id) {return useRows ? (*data)[beginData + int(id)][idsFixed[n]] : (*data)[idsFixed[n]][beginData + int(id)];} int GetznxCount() {return idsx.GetCount();} virtual int GetznyCount(int64 id) const { if (!IsNull(idy) && idy < 0) return (useRows ? (*data)[beginData + int(id)].GetCount() : (*data).GetCount()) + idy; return idsy.GetCount(); } virtual int GetznFixedCount() {return idsFixed.GetCount();} }; class VectorDouble : public DataSource { private: const Vector *xData, *yData; public: VectorDouble(const Vector &_yData, Vector &_xData) : xData(&_xData), yData(&_yData) {} virtual inline double y(int64 id) {return (*yData)[int(id)];} virtual inline double x(int64 id) {return (*xData)[int(id)];} virtual inline int64 GetCount() const {return min(xData->GetCount(), yData->GetCount());} }; class ArrayDouble : public DataSource { private: const Upp::Array *xData, *yData; public: ArrayDouble(const Upp::Array &_yData, Upp::Array &_xData) : xData(&_xData), yData(&_yData) {} virtual inline double y(int64 id) {return (*yData)[int(id)];} virtual inline double x(int64 id) {return (*xData)[int(id)];} virtual inline int64 GetCount() const {return min(xData->GetCount(), yData->GetCount());} }; class VectorPointf : public DataSource { private: const Vector *data; public: VectorPointf() : data(0) {} VectorPointf(const Vector &_data) {Init(&_data);} VectorPointf(Vector *_data) {Init(_data);} void Init(const Vector *_data) {data = _data;} void Init(const Vector &_data) {data = &_data;} virtual inline double y(int64 id) {return (*data)[int(id)].y;} virtual inline double x(int64 id) {return (*data)[int(id)].x;} virtual inline int64 GetCount() const {return data->GetCount();} }; class ArrayPointf : public DataSource { private: Upp::Array *data; public: ArrayPointf(Upp::Array &_data) : data(&_data) {} virtual inline double y(int64 id) {return (*data)[int(id)].y;} virtual inline double x(int64 id) {return (*data)[int(id)].x;} virtual inline int64 GetCount() const {return data->GetCount();} }; template class VectorMapXY : public DataSource { private: VectorMap *data; public: VectorMapXY(VectorMap &_data) : data(&_data) {} virtual inline double y(int64 id) {return (*data)[int(id)];} virtual inline double x(int64 id) {return (*data).GetKey(int(id));} virtual inline int64 GetCount() const {return data->GetCount();} }; template class ArrayMapXY : public DataSource { private: ArrayMap *data; public: ArrayMapXY(ArrayMap &_data) : data(&_data) {} virtual inline double y(int64 id) {return (*data)[int(id)];} virtual inline double x(int64 id) {return (*data).GetKey(int(id));} virtual inline int64 GetCount() const {return data->GetCount();} }; class FuncSource : public DataSource { protected: Function function; public: FuncSource() {isExplicit = true;} FuncSource(Function _function) : function(_function) {isExplicit = true;} virtual inline double f(double x) {return function(x);} virtual double x(int64 ) {NEVER(); return Null;} virtual double y(int64 ) {NEVER(); return Null;} virtual inline int64 GetCount() const {NEVER(); return Null;} }; class FuncSourceV : public DataSource { private: Event function; public: FuncSourceV(Event _function) : function(_function) {isExplicit = true;} virtual inline double f(double x) {double y; function(y, x); return y;} virtual double x(int64 ) {NEVER(); return Null;} virtual double y(int64 ) {NEVER(); return Null;} virtual inline int64 GetCount() const {NEVER(); return Null;} }; class FuncSourcePara : public DataSource { private: Function function; Pointf lastPointf; double lastT; int numPoints; double minT, maxT; public: FuncSourcePara(Function _function, int np, double from, double to) : function(_function), numPoints(np), minT(from), maxT(to) { isParam = true; lastT = Null; } virtual inline double y(double t) { if (IsNull(lastT) || t != lastT) { lastPointf = function(minT + t*(maxT-minT)/numPoints); lastT = t; } return lastPointf.y; } virtual inline double x(double t) { if (IsNull(lastT) || t != lastT) { lastPointf = function(minT + t*(maxT-minT)/numPoints); lastT = t; } return lastPointf.x; } virtual double x(int64 ) {NEVER(); return Null;} virtual double y(int64 ) {NEVER(); return Null;} virtual inline int64 GetCount() const {return numPoints;} }; typedef Event PlotExplicFunc; typedef Function PlotParamFunc; class PlotExplicFuncSource : public DataSource { private: PlotExplicFunc function; public: PlotExplicFuncSource(PlotExplicFunc &_function) : function(_function) {isExplicit = true;} virtual inline double f(double t) {double y; function(y, t); return y;} virtual double x(int64 ) {NEVER(); return Null;} virtual double y(int64 ) {NEVER(); return Null;} virtual inline int64 GetCount() const {NEVER(); return Null;} }; class PlotParamFuncSource : public DataSource { private: PlotParamFunc function; Pointf lastPointf; double lastT; int numPoints; double minT, maxT; public: PlotParamFuncSource(PlotParamFunc _function, int np, double from, double to) : function(_function), numPoints(np), minT(from), maxT(to) { isParam = true; lastT = Null; } inline double y(double t) { if (IsNull(lastT) || t != lastT) { function(lastPointf, minT + t*(maxT-minT)/numPoints); lastT = t; } return lastPointf.y; } inline double x(double t) { if (IsNull(lastT) || t != lastT) { function(lastPointf, minT + t*(maxT-minT)/numPoints); lastT = t; } return lastPointf.x; } virtual double x(int64 ) {NEVER(); return Null;} virtual double y(int64 ) {NEVER(); return Null;} virtual inline int64 GetCount() const {return numPoints;} }; struct PointfLess { bool operator () (const Pointf& a, const Pointf& b) const { return a.x < b.x; } }; class DataSourceSurf { public: DataSourceSurf() : isExplicit(false), key(1212121) {} virtual ~DataSourceSurf() noexcept {key = 1231231;} virtual double z(double x, double y)= 0; virtual bool IsEmpty() = 0; bool IsDeleted() {return key != 1212121;} bool IsExplicit() {return isExplicit;} virtual double MinX() = 0; virtual double MaxX() = 0; virtual double MinY() = 0; virtual double MaxY() = 0; virtual double MinZ() = 0; virtual double MaxZ() = 0; Vector GetIsoline(double thres, const Rectf &area, double deltaX, double deltaY); Vector GetIsolines(const Vector &vals, const Rectf &area, double deltaX, double deltaY); protected: bool isExplicit; private: int key; }; template inline T LinearInterpolate(T x, T x0, T x1, T y0, T y1) { T x1_0 = x1 - x0; if (abs(x1_0) < T(FLT_EPSILON)) return (y0 + y1)/T(2); return ((x1 - x)/x1_0)*y0 + ((x - x0)/x1_0)*y1; } template inline T QuadraticInterpolate(T x, T x0, T x1, T x2, T y0, T y1, T y2) { T x0_1 = x0 - x1; T x0_2 = x0 - x2; T x1_2 = x1 - x2; if (abs(x0_1) < T(FLT_EPSILON)) return LinearInterpolate(x, x0, x2, (y0 + y1)/T(2), y2); else if (abs(x0_2) < T(FLT_EPSILON)) return LinearInterpolate(x, x0, x1, (y0 + y2)/T(2), y1); else if (abs(x1_2) < T(FLT_EPSILON)) return LinearInterpolate(x, x0, x1, y0, (y1 + y2)/T(2)); T x_0 = x - x0; T x_1 = x - x1; T x_2 = x - x2; return ((x_1*x_2)/(x0_1*x0_2))*y0 - ((x_0*x_2)/(x0_1*x1_2))*y1 + ((x_0*x_1)/(x0_2*x1_2))*y2; } template inline T BilinearInterpolate(T x, T y, T x0, T x1, T y0, T y1, T v00, T v01, T v10, T v11) { T r0 = LinearInterpolate(x, x0, x1, v00, v10); T r1 = LinearInterpolate(x, x0, x1, v01, v11); return LinearInterpolate(y, y0, y1, r0, r1); } template inline T TrilinearInterpolate(T x, T y, T z, T x0, T x1, T y0, T y1, T z0, T z1, T v000, T v001, T v010, T v011, T v100, T v101, T v110, T v111) { T x00 = LinearInterpolate(x, x0, x1, v000, v100); T x10 = LinearInterpolate(x, x0, x1, v010, v110); T x01 = LinearInterpolate(x, x0, x1, v001, v101); T x11 = LinearInterpolate(x, x0, x1, v011, v111); T r0 = LinearInterpolate(y, y0, y1, x00, x01); T r1 = LinearInterpolate(y, y0, y1, x10, x11); return LinearInterpolate(z, z0, z1, r0, r1); } template T LinearInterpolate(const T x, const Vector &vecx, const Vector &vecy) { ASSERT(vecx.GetCount() > 1 && vecy.GetCount() > 1); if (x < vecx[0]) return vecx[0]; for (int i = 0; i < vecx.GetCount()-1; ++i) { if (vecx[i+1] >= x && vecx[i] <= x) return LinearInterpolate(x, vecx[i], vecx[i+1], vecy[i], vecy[i+1]); } return vecx[vecx.GetCount()-1]; } class TableInterpolate { public: enum Interpolate {NO, BILINEAR}; protected: Interpolate inter; }; class TableData : public DataSourceSurf, public TableInterpolate { public: typedef double (TableData::*Getdatafun)(int d); TableData() : lendata(0), lenxAxis(0), lenyAxis(0), areas(false) {}; Interpolate Inter() {return inter;} void Inter(Interpolate _inter) {this->inter = _inter;} double z_area(Getdatafun getdataX, Getdatafun getdataY, Getdatafun getdata, double x, double y); double z_point(Getdatafun getdataX, Getdatafun getdataY, Getdatafun getdata, double x, double y); virtual inline double x(int ) {NEVER(); return Null;} virtual inline double y(int ) {NEVER(); return Null;} virtual inline double data(int ) {NEVER(); return Null;} double z(double x, double y) { return z(&TableData::x, &TableData::y, &TableData::data, x, y); } double z(Getdatafun getdataX, Getdatafun getdataY, Getdatafun getdata, double x, double y) { if (areas) return z_area(getdataX, getdataY, getdata, x, y); else return z_point(getdataX, getdataY, getdata, x, y); } bool IsEmpty() { return lendata == 0 || lenxAxis == 0 || lenyAxis == 0; } double MinX(Getdatafun getdata); virtual double MinX() {return MinX(&TableData::x);} double MaxX(Getdatafun getdata); virtual double MaxX() {return MaxX(&TableData::x);} double MinY(Getdatafun getdata); virtual double MinY() {return MinY(&TableData::y);} double MaxY(Getdatafun getdata); virtual double MaxY() {return MaxY(&TableData::y);} double MinZ(Getdatafun getdata); virtual double MinZ() {return MinZ(&TableData::data);} double MaxZ(Getdatafun getdata); virtual double MaxZ() {return MaxZ(&TableData::data);} int lendata; int lenxAxis; int lenyAxis; protected: bool areas; }; class TableDataVector : public TableData { public: TableDataVector() : pdata(0), pxAxis(0), pyAxis(0) {} TableDataVector(Vector &data, Vector &xAxis, Vector &yAxis, Interpolate _inter, bool _areas) {Init(data, xAxis, yAxis, _inter, _areas);} void Init(Vector &data, Vector &xAxis, Vector &yAxis, Interpolate _inter, bool _areas) { ASSERT(_areas ? (data.GetCount() == (xAxis.GetCount() - 1)*(yAxis.GetCount() - 1)) : true); ASSERT(!_areas ? (data.GetCount() == xAxis.GetCount()*yAxis.GetCount()) : true); this->pdata = &data; this->lendata = data.GetCount(); this->pxAxis = &xAxis; this->lenxAxis = xAxis.GetCount(); this->pyAxis = &yAxis; this->lenyAxis = yAxis.GetCount(); this->inter = _inter; this->areas = _areas; } virtual inline double x(int id) {return (*pxAxis)[id];} virtual inline double y(int id) {return (*pyAxis)[id];} virtual inline double data(int id) {return (*pdata)[id];} private: Vector *pdata; Vector *pxAxis; Vector *pyAxis; }; class TableDataCArray : public TableData { public: TableDataCArray() : pdata(0), pxAxis(0), pyAxis(0) {} TableDataCArray(double *data, int _lendata, double *xAxis, int _lenxAxis, double *yAxis, int _lenyAxis, Interpolate _inter, bool _areas) {Init(data, _lendata, xAxis, _lenxAxis, yAxis, _lenyAxis, _inter, _areas);} void Init(double *data, int _lendata, double *xAxis, int _lenxAxis, double *yAxis, int _lenyAxis, Interpolate _inter, bool _areas) { ASSERT(_areas ? (_lendata == (_lenxAxis - 1)*(_lenyAxis - 1)) : true); ASSERT(!_areas ? (_lendata == _lenxAxis*_lenyAxis) : true); this->pdata = data; this->lendata = _lendata; this->pxAxis = xAxis; this->lenxAxis = _lenxAxis; this->pyAxis = yAxis; this->lenyAxis = _lenyAxis; this->inter = _inter; this->areas = _areas; } virtual inline double x(int id) {return pxAxis[id];} virtual inline double y(int id) {return pyAxis[id];} virtual inline double data(int id) {return pdata[id];} private: double *pdata; //int lendata; double *pxAxis; //int lenxAxis; double *pyAxis; //int lenyAxis; }; class ExplicitData : public DataSourceSurf { public: ExplicitData() {} ExplicitData(Function _funz, double _minX, double _maxX, double _minY, double _maxY) { Init(_funz, _minX, _maxX, _minY, _maxY); } void Init(Function funz, double minX, double maxX, double minY, double maxY); double z(double x, double y) {return funz ? funz(x, y) : Null;} bool IsEmpty() {return funz;} double MinX() {return minX;} double MaxX() {return maxX;} double MinY() {return minY;} double MaxY() {return maxY;} double MinZ() {return minZ;} double MaxZ() {return maxZ;} private: double minX, maxX, minY, maxY, minZ, maxZ; Function funz; }; Vector Intersection(Vector &poly1, Vector &poly2); void Simplify(Vector &poly, double dx, double dy); bool SavitzkyGolay_CheckParams(int nleft, int nright, int deg, int der); VectorXd SavitzkyGolay_Coeff(int nleft, int nright, int deg, int der); template typename T::PlainObject Convolution(const MatrixBase& orig, const MatrixBase& kernel, const double factor = 1) { const Eigen::Index ksize = kernel.size(); ASSERT_(ksize % 2 != 0, "Only support odd sized kernels"); ASSERT(orig.size() > ksize); typename T::PlainObject dest(orig.size() - 2 * (ksize/2)); for (typename T::Index row = 0; row < dest.size(); ++row) dest(row) = orig.segment(row, ksize).cwiseProduct(kernel).sum(); if (factor != 1) dest *= factor; return dest; } template typename T::PlainObject Convolution2D(const MatrixBase& orig, const MatrixBase& kernel, const double factor = 1) { const Eigen::Index krows = kernel.rows(); const Eigen::Index kcols = kernel.cols(); ASSERT_(krows % 2 != 0, "Only support odd sized kernels (even rows)"); ASSERT_(kcols % 2 != 0, "Only support odd sized kernels (even cols)"); ASSERT(orig.rows() > krows); ASSERT(orig.cols() > kcols); typename T::PlainObject dest(orig.rows() - 2*(krows/2), orig.cols() - 2*(kcols/2)); for (typename T::Index row = 0; row < dest.rows(); ++row) for (typename T::Index col = 0; col < dest.cols(); ++col) dest(row, col) = orig.block(row, col, krows, kcols).cwiseProduct(kernel).sum(); if (factor != 1) dest *= factor; return dest; } } #endif