1 #ifndef _ScatterDraw_DataSource_h_
2 #define _ScatterDraw_DataSource_h_
3 
4 #include <plugin/Eigen/Eigen.h>
5 
6 namespace Upp {
7 
8 class DataSource : public Pte<DataSource>  {
9 public:
10 	typedef double (DataSource::*Getdatafun)(int64 id);
11 
DataSource()12 	DataSource() : isParam(false), isExplicit(false) {}
~DataSource()13 	virtual ~DataSource() noexcept				{magic = 4321234;}
14 	virtual double y(int64 ) = 0;
15 	virtual double x(int64 ) = 0;
znx(int,int64)16 	virtual double znx(int , int64 ) const		{NEVER();	return Null;}
zny(int,int64)17 	virtual double zny(int , int64 ) const		{NEVER();	return Null;}
znFixed(int,int64)18 	virtual double znFixed(int , int64 )		{NEVER();	return Null;}
y(double)19 	virtual double y(double ) 					{NEVER();	return Null;}
x(double)20 	virtual double x(double ) 					{NEVER();	return Null;}
f(double)21 	virtual double f(double ) 					{NEVER();	return Null;}
f(Vector<double>)22 	virtual double f(Vector<double> ) 			{NEVER();	return Null;}
23 	virtual int64 GetCount() const = 0;
IsEmpty()24 	bool IsEmpty() const						{return GetCount() == 0;}
GetznxCount(int64)25 	virtual int GetznxCount(int64 ) const		{return 0;}
GetznyCount(int64)26 	virtual int GetznyCount(int64 ) const		{return 0;}
GetznFixedCount()27 	virtual int GetznFixedCount() const			{return 0;}
IsParam()28 	bool IsParam() const						{return isParam;}
IsExplicit()29 	bool IsExplicit() const						{return isExplicit;}
30 
SetDestructor(Function<void (void)> _OnDestructor)31 	void SetDestructor(Function <void(void)> _OnDestructor) {OnDestructor = _OnDestructor;}
32 
MinY(int64 & id)33 	double MinY(int64& id)  		{return Min(&DataSource::y, id);}
MinY()34 	double MinY()  					{int64 dummy;	return Min(&DataSource::y, dummy);}
MinX(int64 & id)35 	double MinX(int64& id)  		{return Min(&DataSource::x, id);}
MinX()36 	double MinX() 					{int64 dummy;	return Min(&DataSource::x, dummy);}
37 
MaxY(int64 & id)38 	double MaxY(int64& id)  		{return Max(&DataSource::y, id);}
MaxY()39 	double MaxY()  					{int64 dummy;	return Max(&DataSource::y, dummy);}
MaxX(int64 & id)40 	double MaxX(int64& id)  		{return Max(&DataSource::x, id);}
MaxX()41 	double MaxX() 					{int64 dummy;	return Max(&DataSource::x, dummy);}
42 
IsSortedY()43 	double IsSortedY()  			{return IsSorted(&DataSource::y);}
IsSortedX()44 	double IsSortedX()  			{return IsSorted(&DataSource::x);}
45 
Closest(double x,double y)46 	int64 Closest(double x,double y){return Closest(&DataSource::x, &DataSource::y, x, y);}
ClosestY(double d)47 	int64 ClosestY(double d)  		{return Closest(&DataSource::y, d);}
ClosestX(double d)48 	int64 ClosestX(double d)  		{return Closest(&DataSource::x, d);}
AvgY()49 	double AvgY()  					{return Avg(&DataSource::y);}
AvgX()50 	double AvgX()  					{return Avg(&DataSource::x);}
RMSY()51 	double RMSY()  					{return RMS(&DataSource::y);}
52 	double StdDevY(double avg = Null)  				{return StdDev(&DataSource::y, avg);}
53 	double StdDevX(double avg = Null)  				{return StdDev(&DataSource::x, avg);}
54 	double VarianceY(double avg = Null)  			{return Variance(&DataSource::y, avg);}
UpperEnvelopeY(double width)55 	Vector<int64> UpperEnvelopeY(double width)  	{return UpperEnvelope(&DataSource::y, &DataSource::x, width);}
LowerEnvelopeY(double width)56 	Vector<int64> LowerEnvelopeY(double width)  	{return LowerEnvelope(&DataSource::y, &DataSource::x, width);}
CumulativeY()57 	Vector<Pointf> CumulativeY() 					{return Cumulative(&DataSource::y, &DataSource::x);}
CumulativeAverageY()58 	Vector<Pointf> CumulativeAverageY()  			{return CumulativeAverage(&DataSource::y, &DataSource::x);}
MovingAverageY(double width)59 	Vector<Pointf> MovingAverageY(double width)  	{return MovingAverage(&DataSource::y, &DataSource::x, width);}
SectorAverageY(double width)60 	Vector<Pointf> SectorAverageY(double width)  	{return SectorAverage(&DataSource::y, &DataSource::x, width);}
MaxListY(Vector<int64> & id,double width)61 	void MaxListY(Vector<int64> &id, double width) 	{MaxList(&DataSource::y, &DataSource::x, id, width);}
MaxSubDataImpY(int64 maxId,int width)62 	Pointf MaxSubDataImpY(int64 maxId, int width) 	{return MaxSubDataImp(&DataSource::y, &DataSource::x, maxId, width);}
ZeroCrossingY(bool ascending,bool descending,Vector<double> & zeros,Vector<int64> & ids)63 	void ZeroCrossingY(bool ascending, bool descending, Vector<double> &zeros, Vector<int64> &ids)  {
64 		return ZeroCrossing(&DataSource::y, &DataSource::x, ascending, descending, zeros, ids);}
IntegralY()65 	double IntegralY() 			{return Integral(&DataSource::y, &DataSource::x);}
IntegralY(double from,double to,double n)66 	double IntegralY(double from, double to, double n) 	{return Integral(from, to, n);}
67 
68 	enum FFT_WINDOW {NO_WINDOW = 0, HAMMING, COS};
69 	enum FFT_TYPE   {T_FFT = 0, T_PHASE, T_PSD};
70 
71 	Upp::Vector<Pointf> FFTY(double tSample, bool frequency = false, int type = FFT_TYPE::T_FFT,
72 					int window = FFT_WINDOW::HAMMING, int numSub = 1, double overlapping = 0)  {
73 		return FFT(&DataSource::y, tSample, frequency, type, window, numSub, overlapping);}
GetFFTWindowCount()74 	static int GetFFTWindowCount() 			  {return 3;}
GetFFTWindowStr(int i)75 	static const char *GetFFTWindowStr(int i) {
76 		const char *str[] = {"no window", "hamming", "cos"};
77 		if (i < 0 || i >= GetFFTWindowCount())
78 			return 0;
79 		return str[i];
80 	}
GetSpectralMomentsY(double from,double to,double n,bool frequency,double & m_1,double & m0,double & m1,double & m2)81 	void GetSpectralMomentsY(double from, double to, double n, bool frequency,
82 									double &m_1, double &m0, double &m1, double &m2)
83 		{GetSpectralMoments(from, to, n, frequency, m_1, m0, m1, m2);}
GetSpectralMomentsY(bool frequency,double & m_1,double & m0,double & m1,double & m2)84 	void GetSpectralMomentsY(bool frequency, double &m_1, double &m0, double &m1, double &m2)
85 		{GetSpectralMoments(&DataSource::y, &DataSource::x, frequency, m_1, m0, m1, m2);}
86 
SortDataY()87 	Vector<double> SortDataY() 				{return SortData(&DataSource::y);}
PercentileY(double rate)88 	Vector<double> PercentileY(double rate) {return Percentile(&DataSource::y, rate);}
PercentileValY(double rate)89 	double PercentileValY(double rate) 		{return PercentileVal(&DataSource::y, rate);}
90 
DerivativeY(int orderDer,int orderAcc)91 	Vector<Pointf> DerivativeY(int orderDer, int orderAcc)	  {return Derivative(&DataSource::y, &DataSource::x, orderDer, orderAcc);}
SavitzkyGolayY(int deg,int size,int der)92 	Vector<Pointf> SavitzkyGolayY(int deg, int size, int der) {return SavitzkyGolay(&DataSource::y, &DataSource::x, deg, size, der);}
93 
94 	double Min(Getdatafun getdata, int64& id);
95 	double Max(Getdatafun getdata, int64& id);
96 	double Avg(Getdatafun getdata);
97 	int64 Closest(Getdatafun getdata, double d);
98 	int64 Closest(Getdatafun getdataX, Getdatafun getdataY, double x, double y);
99 	double IsSorted(Getdatafun getdata);
100 	double RMS(Getdatafun getdata);
101 	double StdDev(Getdatafun getdata, double avg = Null);
102 	double Variance(Getdatafun getdata, double avg = Null);
103 	Vector<int64> UpperEnvelope(Getdatafun getdataY, Getdatafun getdataX, double width);
104 	Vector<int64> LowerEnvelope(Getdatafun getdataY, Getdatafun getdataX, double width);
105 	Vector<Pointf> Cumulative(Getdatafun getdataY, Getdatafun getdataX);
106 	Vector<Pointf> CumulativeAverage(Getdatafun getdataY, Getdatafun getdataX);
107 	Vector<Pointf> MovingAverage(Getdatafun getdataY, Getdatafun getdataX, double width);
108 	Vector<Pointf> SectorAverage(Getdatafun getdataY, Getdatafun getdataX, double width);
109 	void MaxList(Getdatafun getdataY, Getdatafun getdataX, Vector<int64> &id, double width);
110 	Pointf MaxSubDataImp(Getdatafun getdataY, Getdatafun getdataX, int64 maxId, int64 width);
111 	void ZeroCrossing(Getdatafun getdataY, Getdatafun getdataX, bool ascending, bool descending,
112 							  Vector<double> &zeros, Vector<int64> &ids);
113 	double Integral(Getdatafun getdataY, Getdatafun getdataX);
114 	double Integral(double from, double to, double n);
115 
116 	double SinEstim_Amplitude(double avg = Null);
117 	bool SinEstim_FreqPhase(double &frequency, double &phase, double avg = Null);
118 	Vector<Pointf> FFT(Getdatafun getdata, double tSample, bool frequency = false,
119 					   int type = FFT_TYPE::T_FFT, int window = FFT_WINDOW::HAMMING,
120 					   int numSub = 1, double overlapping = 0);
121 	void GetSpectralMoments(double from, double to, double n, bool frequency,
122 						double &m_1, double &m0, double &m1, double &m2);
123 	void GetSpectralMoments(Getdatafun getdataY, Getdatafun getdataX, bool frequency,
124 						double &m_1, double &m0, double &m1, double &m2);
125 	bool SameX(DataSource &data);
126 	Vector<double> SortData(Getdatafun getdata);
127 	Vector<double> Percentile(Getdatafun getdata, double rate);
128 	double PercentileVal(Getdatafun getdata, double rate);
129 	Vector<Pointf> Derivative(Getdatafun getdataY, Getdatafun getdataX, int orderDer, int orderAcc);
130 	Vector<Pointf> SavitzkyGolay(Getdatafun getdataY, Getdatafun getdataX, int deg, int size, int der);
131 
IsMagic()132 	bool IsMagic() 				{return magic == 1234321;}		// Temporal use, just for testing
133 
134 protected:
135 	bool isParam, isExplicit;
136 
137 private:
138 	Function <void(void)> OnDestructor;
139 	Vector<int64> Envelope(Getdatafun getdataY, Getdatafun getdataX, double width, bool (*fun)(double a, double b));
140 	int magic = 1234321;
141 };
142 
143 class DataXRange : public DataSource {
144 private:
145 	DataSource *data;
146 	double xHigh, xLow;
147 	int count;
148 
149 public:
DataXRange()150 	DataXRange() : data(0), count(1000) {}
DataXRange(DataSource & _data,double _xLow,double _xHigh)151 	DataXRange(DataSource &_data, double _xLow, double _xHigh) {Init(_data, _xLow, _xHigh);}
Init(DataSource & _data,double _xLow,double _xHigh)152 	void Init(DataSource &_data, double _xLow, double _xHigh) {
153 		data = &_data;
154 		isExplicit = _data.IsExplicit();
155 		isParam = _data.IsParam();
156 		xLow = _xLow;
157 		xHigh = _xHigh;
158 		count = 1000;
159 	}
SetCount(int _count)160 	void SetCount(int _count)	{count = _count;}
SetXLow(double _xLow)161 	void SetXLow(double _xLow) 	{xLow = _xLow;}
SetXHigh(double _xHigh)162 	void SetXHigh(double _xHigh){xHigh = _xHigh;}
Check(int64 id)163 	bool Check(int64 id) const {
164 		double x = data->x(id);
165 		if (!IsNull(xHigh) && xHigh < x)
166 			return false;
167 		if (!IsNull(xLow) && xLow > x)
168 			return false;
169 		return true;
170 	}
y(int64 id)171 	virtual inline double y(int64 id) {
172 		if (isExplicit)
173 			return f(xLow + id*(xHigh - xLow)/double(count - 1));
174 		else
175 			return Check(id) ? data->y(id) : Null;
176 	}
x(int64 id)177 	virtual inline double x(int64 id) {
178 		if (isExplicit)
179 			return xLow + id*(xHigh - xLow)/double(count - 1);
180 		else
181 			return Check(id) ? data->x(id) : Null;
182 	}
x(double t)183 	virtual inline double x(double t) {
184 		double x = data->x(t);
185 		if (!IsNull(xHigh) && xHigh < x)
186 			return Null;
187 		if (!IsNull(xLow) && xLow > x)
188 			return Null;
189 		return x;
190 	}
f(double x)191 	virtual double f(double x) {
192 		if (!IsNull(xHigh) && xHigh < x)
193 			return Null;
194 		if (!IsNull(xLow) && xLow > x)
195 			return Null;
196 		return data->f(x);
197 	}
MinX()198 	virtual double MinX() 				{return xLow;}
MaxX()199 	virtual double MaxX() 				{return xHigh;}
GetCount()200 	virtual inline int64 GetCount() const {
201 		if (isExplicit)
202 			return count;
203 		return data->GetCount();
204 	}
205 };
206 
207 class DataReverse : public DataSource {
208 private:
209 	DataSource *data;
210 
211 public:
DataReverse()212 	DataReverse() : data(0) {}
DataReverse(DataSource & _data)213 	DataReverse(DataSource &_data) {Init(_data);}
Init(DataSource * _data)214 	void Init(DataSource *_data)   {Init(*_data);}
Init(DataSource & _data)215 	void Init(DataSource &_data) {
216 		ASSERT(!_data.IsExplicit() && !_data.IsParam());
217 		data = &_data;
218 	}
y(int64 id)219 	virtual inline double y(int64 id) {return data->y(GetCount() - id - 1);}
x(int64 id)220 	virtual inline double x(int64 id) {return data->x(GetCount() - id - 1);}
GetCount()221 	virtual int64 GetCount() const	  {return data->GetCount();}
222 };
223 
224 class DataReverseX : public DataSource {
225 private:
226 	DataSource *data;
227 
228 public:
DataReverseX()229 	DataReverseX() : data(0) {}
DataReverseX(DataSource & _data)230 	DataReverseX(DataSource &_data) {Init(_data);}
Init(DataSource & _data)231 	void Init(DataSource &_data) {
232 		ASSERT(!_data.IsExplicit() && !_data.IsParam());
233 		data = &_data;
234 	}
y(int64 id)235 	virtual inline double y(int64 id) {return data->y(id);}
x(int64 id)236 	virtual inline double x(int64 id) {return data->x(GetCount() - id - 1);}
GetCount()237 	virtual int64 GetCount() const	  {return data->GetCount();}
238 };
239 
240 class DataAppend : public DataSource {
241 protected:
242 	DataSource *data1, *data2;
243 
244 public:
DataAppend()245 	DataAppend() : data1(0), data2(0) {}
DataAppend(DataSource & _data1,DataSource & _data2)246 	DataAppend(DataSource &_data1, DataSource &_data2) {Init(_data1, _data2);}
Init(DataSource & _data1,DataSource & _data2)247 	void Init(DataSource &_data1, DataSource &_data2) {
248 		ASSERT(!_data1.IsExplicit() && !_data1.IsParam() && !_data2.IsExplicit() && !_data2.IsParam());
249 		data1 = &_data1;
250 		data2 = &_data2;
251 	}
y(int64 id)252 	virtual inline double y(int64 id) {
253 		int64 count1 = data1->GetCount();
254 		if (id < count1)
255 			return data1->y(id);
256 		return data2->y(id - count1);
257 	}
x(int64 id)258 	virtual inline double x(int64 id) {
259 		int64 count1 = data1->GetCount();
260 		if (id < count1)
261 			return data1->x(id);
262 		return data2->x(id - count1);
263 	}
GetCount()264 	virtual int64 GetCount() const		{return data1->GetCount() + data2->GetCount();}
265 };
266 
267 class DataRange : public DataAppend {
268 public:
DataRange()269 	DataRange() : DataAppend() {}
DataRange(DataSource & _data1,DataSource & _data2)270 	DataRange(DataSource &_data1, DataSource &_data2) {Init(_data1, _data2);}
Init(DataSource & _data1,DataSource & _data2)271 	void Init(DataSource &_data1, DataSource &_data2) {
272 		ASSERT(!_data1.IsExplicit() && !_data1.IsParam() && !_data2.IsExplicit() && !_data2.IsParam());
273 		data1 = &_data1;
274 		rev.Init(_data2);
275 		data2 = &rev;
276 	}
277 private:
278 	DataReverse rev;
279 };
280 
281 class DataStackedY {
282 public:
DataStackedY()283 	DataStackedY() : is100(false) {}
Set100(bool _is100)284 	void Set100(bool _is100)	  {is100 = _is100;}
Add(DataSource & data)285 	DataStackedY &Add(DataSource &data) {
286 		EachDataStackedY &each = eachData.Add();
287 		each.Init(data, eachData.GetCount() -1, this);
288 		return *this;
289 	}
Get100Y(int index,int64 id)290 	double Get100Y(int index, int64 id) {
291 		double acc = 0;
292 		for (int i = 0; i < eachData.GetCount(); ++i)
293 			acc += eachData[i].RealY(id);
294 		if (acc == 0)
295 			return 0;
296 		else
297 			return 100*eachData[index].RealY(id)/acc;
298 	}
GetY(int index,int64 id)299 	double GetY(int index, int64 id) {
300 		double res = 0;
301 		for (int i = 0; i <= index; ++i) {
302 			if (is100)
303 				res += Get100Y(i, id);
304 			else
305 				res += eachData[i].RealY(id);
306 		}
307 		return res;
308 	}
309 
310 	class EachDataStackedY : public DataSource {
311 	public:
EachDataStackedY()312 		EachDataStackedY() {}
Init(DataSource & _data,int _index,DataStackedY * _parent)313 		void Init(DataSource &_data, int _index, DataStackedY *_parent) {
314 			ASSERT(!_data.IsExplicit() && !_data.IsParam());
315 			this->data = &_data;
316 			this->index = _index;
317 			this->parent = _parent;
318 		}
y(int64 id)319 		virtual inline double y(int64 id) {
320 			return parent->GetY(index, id);
321 		}
RealY(int64 id)322 		double RealY(int64 id) {
323 			return data->y(id);
324 		}
x(int64 id)325 		virtual inline double x(int64 id) {
326 			return data->x(id);
327 		}
GetCount()328 		virtual int64 GetCount() const {
329 			return data->GetCount();
330 		}
331 	private:
332 		DataSource *data = 0;
333 		int index = -1;
334 		DataStackedY *parent = 0;
335 	};
336 
Get(int id)337 	EachDataStackedY &Get(int id) {return eachData[id];}
338 
339 protected:
340 	Array<EachDataStackedY> eachData;
341 	bool is100;
342 };
343 
344 class CArray : public DataSource {
345 private:
346 	const double *yData, *xData, *zData;
347 	int64 numData;
348 	double x0, deltaX;
349 
350 public:
CArray(const double * _yData,int _numData,double _x0,double _deltaX)351 	CArray(const double *_yData, int _numData, double _x0, double _deltaX) : yData(_yData), numData(_numData), x0(_x0), deltaX(_deltaX) {xData = NULL;}
CArray(const double * _yData,const double * _xData,int _numData)352 	CArray(const double *_yData, const double *_xData, int _numData) : yData(_yData), xData(_xData), numData(_numData) {zData = nullptr; x0 = deltaX = 0;}
CArray(const double * _yData,const double * _xData,const double * _zData,int _numData)353 	CArray(const double *_yData, const double *_xData, const double *_zData, int _numData) : yData(_yData), xData(_xData), zData(_zData), numData(_numData) {x0 = deltaX = 0;}
y(int64 id)354 	virtual inline double y(int64 id)  	{return yData[ptrdiff_t(id)];}
x(int64 id)355 	virtual inline double x(int64 id)  	{return xData ? xData[ptrdiff_t(id)] : id*deltaX + x0;}
356 	virtual double znFixed(int n, int64 id);
GetznFixedCount()357 	virtual int GetznFixedCount() const			{return 1;}
GetCount()358 	virtual inline int64 GetCount() const		{return numData;}
359 };
360 
361 class EigenVector : public DataSource {
362 private:
363 	const Eigen::VectorXd *xData, *yData, *zData;
364 	double x0, deltaX;
365 
366 public:
EigenVector(const Eigen::VectorXd & _yData,double _x0,double _deltaX)367 	EigenVector(const Eigen::VectorXd &_yData, double _x0, double _deltaX) : yData(&_yData), x0(_x0), deltaX(_deltaX) {xData = nullptr;}
EigenVector(const Eigen::VectorXd & _xData,const Eigen::VectorXd & _yData)368 	EigenVector(const Eigen::VectorXd &_xData, const Eigen::VectorXd &_yData) : xData(&_xData), yData(&_yData) {zData = nullptr; x0 = deltaX = 0;}
EigenVector(const Eigen::VectorXd & _xData,const Eigen::VectorXd & _yData,const Eigen::VectorXd & _zData)369 	EigenVector(const Eigen::VectorXd &_xData, const Eigen::VectorXd &_yData, const Eigen::VectorXd &_zData) : xData(&_xData), yData(&_yData), zData(&_zData) {x0 = deltaX = 0;}
x(int64 id)370 	virtual inline double x(int64 id)  	{return xData ? (*xData)(Eigen::Index(id)) : id*deltaX + x0;}
y(int64 id)371 	virtual inline double y(int64 id)  	{return (*yData)(Eigen::Index(id));}
znFixed(int n,int64 id)372 	virtual double znFixed(int n, int64 id) {
373 		if (n == 0)
374 			return (*zData)(Eigen::Index(id));
375 		NEVER();
376 		return Null;
377 	}
GetznFixedCount()378 	virtual int GetznFixedCount() const			{return 1;}
GetCount()379 	virtual inline int64 GetCount() const		{return yData->size();}
380 };
381 
382 template <class Y>
383 class VectorY : public DataSource {
384 private:
385 	const Vector<Y> *yData;
386 	double x0, deltaX;
387 
388 public:
VectorY()389 	VectorY() : yData(0), x0(0), deltaX(0) {}
390 	VectorY(const Vector<Y> &_yData, double _x0 = 0, double _deltaX = 1) {Init(_yData, _x0, _deltaX);}
391 	void Init(const Vector<Y> &_yData, double _x0 = 0, double _deltaX = 1) {
392 		this->yData = &_yData;
393 		this->x0 = _x0;
394 		this->deltaX = _deltaX;
395 	}
y(int64 id)396 	virtual inline double y(int64 id) 		{return (*yData)[int(id)];}
x(int64 id)397 	virtual inline double x(int64 id) 		{return id*deltaX + x0;}
GetCount()398 	virtual inline int64 GetCount() const	{return yData->GetCount();}
MinX()399 	virtual double MinX() 					{return x0;}
MaxX()400 	virtual double MaxX() 					{return x0 + (yData->GetCount() - 1)*deltaX;}
AvgX()401 	virtual double AvgX() 					{return x0 + ((yData->GetCount() - 1)*deltaX)/2.;}
402 };
403 
404 template <class Y>
405 class ArrayY : public DataSource {
406 private:
407 	const Upp::Array<Y> *yData = 0;
408 	double x0 = 0, deltaX = 0;
409 
410 public:
ArrayY()411 	ArrayY() {}
412 	ArrayY(const Upp::Array<Y> &_yData, double _x0 = 0, double _deltaX = 1) {Init(_yData, _x0, _deltaX);}
413 	void Init(const Upp::Array<Y> &_yData, double _x0 = 0, double _deltaX = 1) {
414 		this->yData = &_yData;
415 		this->x0 = _x0;
416 		this->deltaX = _deltaX;
417 	}
y(int64 id)418 	virtual inline double y(int64 id) 		{return (*yData)[ptrdiff_t(id)];}
x(int64 id)419 	virtual inline double x(int64 id) 		{return id*deltaX + x0;}
GetCount()420 	virtual inline int64 GetCount() const	{return yData->GetCount();}
MinX()421 	virtual double MinX() 					{return x0;}
MaxX()422 	virtual double MaxX() 					{return x0 + yData->GetCount()*deltaX;}
AvgX()423 	virtual double AvgX() 					{return (x0 + yData->GetCount()*deltaX)/2.;}
424 };
425 
426 template <class Y>
427 class VectorVectorY : public DataSource {
428 private:
429 	const Vector<Vector<Y> > *data = 0;
430 	bool useRows = true;
431 	int idx = 0, idy = 1;
432 	Vector<int> idsx, idsy, idsFixed;
433 	int beginData = 0;
434 	int numData = Null;
435 
436 public:
VectorVectorY()437 	VectorVectorY() {}
438 	VectorVectorY(const Vector<Vector<Y> > &_data, int _idx, int _idy,
439 				  const Vector<int> &_idsx, const Vector<int> &_idsy, const Vector<int> &_idsFixed,
440 				  bool _useRows = true, int _beginData = 0, int _numData = Null) {
441 		Init(_data, _idx, _idy, _idsx, _idsy, _idsFixed, _useRows, _beginData, _numData);
442 	}
443 	void Init(const Vector<Vector<Y> > &_data, int _idx, int _idy, const Vector<int> &_idsx, const Vector<int> &_idsy,
444 			  const Vector<int> &_idsFixed, bool _useRows = true, int _beginData = 0, int _numData = Null) {
445 		this->data = &_data;
446 		this->useRows = _useRows;
447 
448 		this->idx = _idx;
449 		this->idy = _idy;
450 		this->idsx = clone(_idsx);
451 		this->idsy = clone(_idsy);
452 		this->idsFixed = clone(_idsFixed);
453 		this->beginData = _beginData;
454 		this->numData = _numData;
455 		if (IsNull(_numData)) {
456 			if (!_useRows) {
457 				if (_data.IsEmpty())
458 					this->numData = 0;
459 				else
460 					this->numData = _data[0].GetCount() - _beginData;
461 			} else
462 				this->numData = _data.GetCount() - _beginData;
463 		}
464 	}
465 	void Init(const Vector<Vector<Y> > &_data, int _idx, int _idy, bool _useRows = true, int _beginData = 0, int _numData = Null) {
466 		static Vector<int> idsVoid;
467 		Init(_data, _idx, _idy, idsVoid, idsVoid, idsVoid, _useRows, _beginData, _numData);
468 	}
y(int64 id)469 	virtual inline double y(int64 id)  {
470 		if (!IsNull(idy) && idy >= 0) {
471 			if (useRows)
472 				return (*data)[beginData + int(id)][idy];
473 			else
474 				return (*data)[idy][beginData + int(id)];
475 		} else {
476 			if (GetznyCount(id) == 0)
477 				return Null;
478 			double ret = 0;
479 			for (int i = 0; i < GetznyCount(id); ++i)
480 				ret += zny(i, id);
481 			return ret/GetznyCount(id);
482 		}
483 	}
x(int64 id)484 	virtual inline double x(int64 id)  {return useRows ? (*data)[beginData + int(id)][idx] : (*data)[idx][beginData + int(id)];}
485 	//virtual inline double xn(int n, int64 id) 	{return useRows ? (*data)[beginData + int(id)][ids[n]] : (*data)[ids[n]][beginData + int(id)];}
GetCount()486 	virtual inline int64 GetCount() const	{return numData;};
znx(int n,int64 id)487 	virtual double znx(int n, int64 id)	const {
488 		return useRows ? (*data)[beginData + int(id)][idsx[n]] : (*data)[idsx[n]][beginData + int(id)];}
zny(int n,int64 id)489 	virtual double zny(int n, int64 id)	const {
490 		if (!IsNull(idy) && idy < 0)
491 			return useRows ? (*data)[beginData + int(id)][n - idy] : (*data)[n - idy][beginData + int(id)];
492 		return useRows ? (*data)[beginData + int(id)][idsy[n]] : (*data)[idsy[n]][beginData + int(id)];
493 	}
znFixed(int n,int64 id)494 	virtual double znFixed(int n, int64 id)	{return useRows ? (*data)[beginData + int(id)][idsFixed[n]] : (*data)[idsFixed[n]][beginData + int(id)];}
GetznxCount(int64)495 	virtual int GetznxCount(int64) const	{
496 		return idsx.GetCount();}
GetznyCount(int64 id)497 	virtual int GetznyCount(int64 id) const {
498 		if (!IsNull(idy) && idy < 0)
499 			return (useRows ? (*data)[beginData + int(id)].GetCount() : (*data).GetCount()) + idy;
500 		return idsy.GetCount();
501 	}
GetznFixedCount()502 	virtual int GetznFixedCount() const		{return idsFixed.GetCount();}
503 };
504 
505 class VectorXY : public DataSource {
506 private:
507 	const Vector<double> *xData, *yData;
508 
509 public:
VectorXY(const Vector<double> & _xData,const Vector<double> & _yData)510 	VectorXY(const Vector<double> &_xData, const Vector<double> &_yData) : xData(&_xData), yData(&_yData) {}
x(int64 id)511 	virtual inline double x(int64 id) 		{return (*xData)[int(id)];}
y(int64 id)512 	virtual inline double y(int64 id) 		{return (*yData)[int(id)];}
GetCount()513 	virtual inline int64 GetCount()	 const	{return min(xData->GetCount(), yData->GetCount());}
514 };
515 
516 class ArrayXY : public DataSource {
517 private:
518 	const Upp::Array<double> *xData, *yData;
519 
520 public:
ArrayXY(const Upp::Array<double> & _xData,const Upp::Array<double> & _yData)521 	ArrayXY(const Upp::Array<double> &_xData, const Upp::Array<double> &_yData) : xData(&_xData), yData(&_yData) {}
x(int64 id)522 	virtual inline double x(int64 id) 		{return (*xData)[int(id)];}
y(int64 id)523 	virtual inline double y(int64 id) 		{return (*yData)[int(id)];}
GetCount()524 	virtual inline int64 GetCount() const	{return min(xData->GetCount(), yData->GetCount());}
525 };
526 
527 /* Replaced by VectorXY and ArrayXY
528 class VectorDouble : public DataSource {
529 private:
530 	const Vector<double> *xData, *yData;
531 
532 public:
533 	VectorDouble(const Vector<double> &_yData, Vector<double> &_xData) : xData(&_xData), yData(&_yData) {}
534 	virtual inline double y(int64 id) 		{return (*yData)[int(id)];}
535 	virtual inline double x(int64 id) 		{return (*xData)[int(id)];}
536 	virtual inline int64 GetCount()	 const	{return min(xData->GetCount(), yData->GetCount());}
537 };
538 
539 class ArrayDouble : public DataSource {
540 private:
541 	const Upp::Array<double> *xData, *yData;
542 
543 public:
544 	ArrayDouble(const Upp::Array<double> &_yData, Upp::Array<double> &_xData) : xData(&_xData), yData(&_yData) {}
545 	virtual inline double y(int64 id) 		{return (*yData)[int(id)];}
546 	virtual inline double x(int64 id) 		{return (*xData)[int(id)];}
547 	virtual inline int64 GetCount() const	{return min(xData->GetCount(), yData->GetCount());}
548 };*/
549 
550 class VectorPointf : public DataSource {
551 private:
552 	const Vector<Pointf> *data;
553 
554 public:
VectorPointf()555 	VectorPointf() : data(0) {}
VectorPointf(const Vector<Pointf> & _data)556 	VectorPointf(const Vector<Pointf> &_data)	{Init(&_data);}
VectorPointf(Vector<Pointf> * _data)557 	VectorPointf(Vector<Pointf> *_data) 		{Init(_data);}
Init(const Vector<Pointf> * _data)558 	void Init(const Vector<Pointf> *_data) 		{data = _data;}
Init(const Vector<Pointf> & _data)559 	void Init(const Vector<Pointf> &_data) 		{data = &_data;}
y(int64 id)560 	virtual inline double y(int64 id) 			{return (*data)[int(id)].y;}
x(int64 id)561 	virtual inline double x(int64 id) 	 		{return (*data)[int(id)].x;}
GetCount()562 	virtual inline int64 GetCount() const		{return data->GetCount();}
563 };
564 
565 class ArrayPointf : public DataSource {
566 private:
567 	const Upp::Array<Pointf> *data;
568 
569 public:
ArrayPointf(const Upp::Array<Pointf> & _data)570 	ArrayPointf(const Upp::Array<Pointf> &_data) : data(&_data) {}
y(int64 id)571 	virtual inline double y(int64 id) 		{return (*data)[int(id)].y;}
x(int64 id)572 	virtual inline double x(int64 id) 	 {return (*data)[int(id)].x;}
GetCount()573 	virtual inline int64 GetCount() const	{return data->GetCount();}
574 };
575 
576 template <class X, class Y>
577 class VectorMapXY : public DataSource {
578 private:
579 	const VectorMap<X, Y> *data;
580 
581 public:
VectorMapXY(const VectorMap<X,Y> & _data)582 	VectorMapXY(const VectorMap<X, Y> &_data) : data(&_data) {}
y(int64 id)583 	virtual inline double y(int64 id) 			{return (*data)[int(id)];}
x(int64 id)584 	virtual inline double x(int64 id) 	 	{return (*data).GetKey(int(id));}
GetCount()585 	virtual inline int64 GetCount() const		{return data->GetCount();}
586 };
587 
588 template <class X, class Y>
589 class ArrayMapXY : public DataSource {
590 private:
591 	const ArrayMap<X, Y> *data;
592 
593 public:
ArrayMapXY(const ArrayMap<X,Y> & _data)594 	ArrayMapXY(const ArrayMap<X, Y> &_data) : data(&_data) {}
y(int64 id)595 	virtual inline double y(int64 id) 			{return (*data)[int(id)];}
x(int64 id)596 	virtual inline double x(int64 id) 		 	{return (*data).GetKey(int(id));}
GetCount()597 	virtual inline int64 GetCount() const		{return data->GetCount();}
598 };
599 
600 class FuncSource : public DataSource {
601 protected:
602 	Function <double(double)> function;
603 
604 public:
FuncSource()605 	FuncSource() {isExplicit = true;}
FuncSource(Function<double (double)> _function)606 	FuncSource(Function <double(double)> _function) : function(_function) {isExplicit = true;}
f(double x)607 	virtual inline double f(double x)		{return function(x);}
x(int64)608 	virtual double x(int64 ) 				{NEVER(); return Null;}
y(int64)609 	virtual double y(int64 ) 				{NEVER(); return Null;}
GetCount()610 	virtual inline int64 GetCount() const	{return 0;}
611 };
612 
613 class FuncSourceV : public DataSource {
614 private:
615 	Event<double&, double> function;
616 
617 public:
FuncSourceV(Event<double &,double> _function)618 	FuncSourceV(Event<double&, double> _function) : function(_function) {isExplicit = true;}
f(double x)619 	virtual inline double f(double x)		{double y; function(y, x); return y;}
x(int64)620 	virtual double x(int64 ) 				{NEVER(); return Null;}
y(int64)621 	virtual double y(int64 ) 				{NEVER(); return Null;}
GetCount()622 	virtual inline int64 GetCount() const	{return 0;}
623 };
624 
625 class FuncSourcePara : public DataSource {
626 private:
627 	Function <Pointf(double)> function;
628 	Pointf lastPointf;
629 	double lastT;
630 	int numPoints;
631 	double minT, maxT;
632 
633 public:
FuncSourcePara(Function<Pointf (double)> _function,int np,double from,double to)634 	FuncSourcePara(Function <Pointf(double)> _function, int np, double from, double to) :
635 							function(_function), numPoints(np), minT(from), maxT(to) {
636 		isParam = true;
637 		lastT = Null;
638 	}
y(double t)639 	virtual inline double y(double t) {
640 		if (IsNull(lastT) || t != lastT) {
641 			lastPointf = function(minT + t*(maxT-minT)/numPoints);
642 			lastT = t;
643 		}
644 		return lastPointf.y;
645 	}
x(double t)646 	virtual inline double x(double t) {
647 		if (IsNull(lastT) || t != lastT) {
648 			lastPointf = function(minT + t*(maxT-minT)/numPoints);
649 			lastT = t;
650 		}
651 		return lastPointf.x;
652 	}
x(int64)653 	virtual double x(int64 ) 				{NEVER(); return Null;}
y(int64)654 	virtual double y(int64 ) 				{NEVER(); return Null;}
GetCount()655 	virtual inline int64 GetCount() const	{return numPoints;}
656 };
657 
658 typedef Event<double&, double> PlotExplicFunc;
659 typedef Function<void(Pointf&, double)> PlotParamFunc;
660 
661 
662 class PlotExplicFuncSource : public DataSource {
663 private:
664 	PlotExplicFunc function;
665 
666 public:
PlotExplicFuncSource(PlotExplicFunc & _function)667 	PlotExplicFuncSource(PlotExplicFunc &_function) : function(_function) {isExplicit = true;}
f(double t)668 	virtual inline double f(double t)	{double y; function(y, t); return y;}
x(int64)669 	virtual double x(int64 ) 				{NEVER(); return Null;}
y(int64)670 	virtual double y(int64 ) 				{NEVER(); return Null;}
GetCount()671 	virtual inline int64 GetCount() const	{NEVER(); return Null;}
672 };
673 
674 class PlotParamFuncSource : public DataSource {
675 private:
676 	PlotParamFunc function;
677 	Pointf lastPointf;
678 	double lastT;
679 	int numPoints;
680 	double minT, maxT;
681 
682 public:
PlotParamFuncSource(PlotParamFunc _function,int np,double from,double to)683 	PlotParamFuncSource(PlotParamFunc _function, int np, double from, double to) :
684 						function(_function), numPoints(np), minT(from), maxT(to) {
685 		isParam = true;
686 		lastT = Null;
687 	}
y(double t)688 	inline double y(double t) {
689 		if (IsNull(lastT) || t != lastT) {
690 			function(lastPointf, minT + t*(maxT-minT)/numPoints);
691 			lastT = t;
692 		}
693 		return lastPointf.y;
694 	}
x(double t)695 	inline double x(double t) {
696 		if (IsNull(lastT) || t != lastT) {
697 			function(lastPointf, minT + t*(maxT-minT)/numPoints);
698 			lastT = t;
699 		}
700 		return lastPointf.x;
701 	}
x(int64)702 	virtual double x(int64 ) 				{NEVER(); return Null;}
y(int64)703 	virtual double y(int64 ) 				{NEVER(); return Null;}
GetCount()704 	virtual inline int64 GetCount() const	{return numPoints;}
705 };
706 
707 struct PointfLess {
operatorPointfLess708 	bool operator () (const Pointf& a, const Pointf& b) const { return a.x < b.x; }
709 };
710 
711 class DataSourceSurf {
712 public:
DataSourceSurf()713 	DataSourceSurf() : isExplicit(false), key(1212121) {}
~DataSourceSurf()714 	virtual ~DataSourceSurf() noexcept	{key = 1231231;}
715 	virtual double z(double x, double y)= 0;
716 
717 	virtual bool IsEmpty() = 0;
IsDeleted()718 	bool IsDeleted()	   {return key != 1212121;}
IsExplicit()719 	bool IsExplicit()	   {return isExplicit;}
720 
721 	virtual double MinX() = 0;
722 	virtual double MaxX() = 0;
723 	virtual double MinY() = 0;
724 	virtual double MaxY() = 0;
725 	virtual double MinZ() = 0;
726 	virtual double MaxZ() = 0;
727 
728 	Vector<Pointf> GetIsoline(double thres, const Rectf &area, double deltaX, double deltaY);
729 	Vector<Pointf> GetIsolines(const Vector<double> &vals, const Rectf &area, double deltaX, double deltaY);
730 
731 protected:
732 	bool isExplicit;
733 
734 private:
735 	int key;
736 };
737 
738 template <class T>
LinearInterpolate(T x,T x0,T x1,T y0,T y1)739 inline T LinearInterpolate(T x, T x0, T x1, T y0, T y1) {
740 	T x1_0 = x1 - x0;
741 	if (abs(x1_0) < T(FLT_EPSILON))
742 		return (y0 + y1)/T(2);
743 
744   	return y0 + (x - x0)*(y1 - y0)/x1_0;
745 }
746 
747 template <class T>
QuadraticInterpolate(T x,T x0,T x1,T x2,T y0,T y1,T y2)748 inline T QuadraticInterpolate(T x, T x0, T x1, T x2, T y0, T y1, T y2) {
749 	T x0_1 = x0 - x1;
750 	T x0_2 = x0 - x2;
751 	T x1_2 = x1 - x2;
752 	if (abs(x0_1) < T(FLT_EPSILON))
753 		return LinearInterpolate(x, x0, x2, (y0 + y1)/T(2), y2);
754 	else if (abs(x0_2) < T(FLT_EPSILON))
755 		return LinearInterpolate(x, x0, x1, (y0 + y2)/T(2), y1);
756 	else if (abs(x1_2) < T(FLT_EPSILON))
757 		return LinearInterpolate(x, x0, x1, y0, (y1 + y2)/T(2));
758 
759 	T x_0 = x - x0;
760 	T x_1 = x - x1;
761 	T x_2 = x - x2;
762 
763   	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;
764 }
765 
766 template <class T>
BilinearInterpolate(T x,T y,T x0,T x1,T y0,T y1,T v00,T v01,T v10,T v11)767 inline T BilinearInterpolate(T x, T y, T x0, T x1, T y0, T y1, T v00, T v01, T v10, T v11) {
768 	T r0 = LinearInterpolate(x, x0, x1, v00, v10);
769 	T r1 = LinearInterpolate(x, x0, x1, v01, v11);
770 
771 	return LinearInterpolate(y, y0, y1, r0, r1);
772 }
773 
774 template <class 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)775 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) {
776 	T x00 = LinearInterpolate(x, x0, x1, v000, v100);
777 	T x10 = LinearInterpolate(x, x0, x1, v010, v110);
778 	T x01 = LinearInterpolate(x, x0, x1, v001, v101);
779 	T x11 = LinearInterpolate(x, x0, x1, v011, v111);
780 	T r0  = LinearInterpolate(y, y0, y1, x00,  x01);
781 	T r1  = LinearInterpolate(y, y0, y1, x10,  x11);
782 
783 	return LinearInterpolate(z, z0, z1, r0, r1);
784 }
785 
786 template <class T>
LinearInterpolate(const T x,const Point_<T> * vec,int len)787 T LinearInterpolate(const T x, const Point_<T> *vec, int len) {
788 	ASSERT(len > 1);
789 	if (x < vec[0].x)
790 		return vec[0].y;
791 	for (int i = 0; i < len-1; ++i) {
792 		if (vec[i+1].x >= x && vec[i].x <= x)
793 			return LinearInterpolate(x, vec[i].x, vec[i+1].x, vec[i].y, vec[i+1].y);
794 	}
795 	return vec[len-1].y;
796 }
797 
798 template <class Range, class T>
LinearInterpolate(const T x,const Range & vec)799 T LinearInterpolate(const T x, const Range &vec) {
800 	ASSERT(vec.GetCount() > 1);
801 	return LinearInterpolate(x, (const T *)vec, vec.GetCount());
802 }
803 
804 template <class T>
GetInterpolatePos(const T x,const T * vecx,int len,int & x0,int & x1)805 void GetInterpolatePos(const T x, const T *vecx, int len, int &x0, int &x1) {
806 	if (x < vecx[0]) {
807 		x0 = x1 = 0;
808 		return;
809 	}
810 	for (int i = 0; i < len-1; ++i) {
811 		if (vecx[i+1] >= x && vecx[i] <= x) {
812 			x0 = i;
813 			x1 = i+1;
814 			return;
815 		}
816 	}
817 	x0 = x1 = len-1;
818 }
819 
820 template <class Range, class T>
GetInterpolatePos(const T x,const Range & vecx,int & x0,int & x1)821 void GetInterpolatePos(const T x, const Range &vecx, int &x0, int &x1) {
822 	ASSERT(vecx.GetCount() > 1);
823 	GetInterpolatePos(x, (const T *)vecx, vecx.GetCount(), x0, x1);
824 }
825 
826 template <class T>
LinearInterpolate(const T x,const T * vecx,const T * vecy,int len)827 T LinearInterpolate(const T x, const T *vecx, const T *vecy, int len) {
828 	ASSERT(len > 1);
829 	if (x < vecx[0])
830 		return vecy[0];
831 	for (int i = 0; i < len-1; ++i) {
832 		if (vecx[i+1] >= x && vecx[i] <= x)
833 			return LinearInterpolate(x, vecx[i], vecx[i+1], vecy[i], vecy[i+1]);
834 	}
835 	return vecy[len-1];
836 }
837 
838 template <class Range, class T>
LinearInterpolate(const T x,const Range & vecx,const Range & vecy)839 T LinearInterpolate(const T x, const Range &vecx, const Range &vecy) {
840 	ASSERT(vecx.GetCount() > 1);
841 	ASSERT(vecx.GetCount() == vecy.GetCount());
842 	return LinearInterpolate(x, (const T *)vecx, (const T *)vecy, vecx.GetCount());
843 }
844 
845 class TableInterpolate {
846 public:
847 	enum Interpolate {NO, BILINEAR};
848 
849 protected:
850 	Interpolate inter;
851 };
852 
853 
854 class TableData : public DataSourceSurf, public TableInterpolate {
855 public:
856 	typedef double (TableData::*Getdatafun)(int d);
857 
TableData()858 	TableData() : lendata(0), lenxAxis(0), lenyAxis(0), areas(false) {};
859 
Inter()860 	Interpolate Inter()				{return inter;}
Inter(Interpolate _inter)861 	void Inter(Interpolate _inter)	{this->inter = _inter;}
862 
863 	double z_area(Getdatafun getdataX, Getdatafun getdataY, Getdatafun getdata,
864 					double x, double y);
865 	double z_point(Getdatafun getdataX, Getdatafun getdataY, Getdatafun getdata,
866 					double x, double y);
867 
x(int)868 	virtual inline double x(int )		{NEVER();	return Null;}
y(int)869 	virtual inline double y(int )		{NEVER();	return Null;}
data(int)870 	virtual inline double data(int )	{NEVER();	return Null;}
871 
z(double x,double y)872 	double z(double x, double y) {
873 		return z(&TableData::x, &TableData::y, &TableData::data, x, y);
874 	}
z(Getdatafun getdataX,Getdatafun getdataY,Getdatafun getdata,double x,double y)875 	double z(Getdatafun getdataX, Getdatafun getdataY, Getdatafun getdata, double x, double y) {
876 		if (areas)
877 			return z_area(getdataX, getdataY, getdata, x, y);
878 		else
879 			return z_point(getdataX, getdataY, getdata, x, y);
880 	}
881 
IsEmpty()882 	bool IsEmpty() {
883 		return lendata == 0 || lenxAxis == 0 || lenyAxis == 0;
884 	}
885 
886 	double MinX(Getdatafun getdata);
MinX()887 	virtual double MinX() 				{return MinX(&TableData::x);}
888 	double MaxX(Getdatafun getdata);
MaxX()889 	virtual double MaxX() 				{return MaxX(&TableData::x);}
890 	double MinY(Getdatafun getdata);
MinY()891 	virtual double MinY() 				{return MinY(&TableData::y);}
892 	double MaxY(Getdatafun getdata);
MaxY()893 	virtual double MaxY() 				{return MaxY(&TableData::y);}
894 	double MinZ(Getdatafun getdata);
MinZ()895 	virtual double MinZ() 				{return MinZ(&TableData::data);}
896 	double MaxZ(Getdatafun getdata);
MaxZ()897 	virtual double MaxZ() 				{return MaxZ(&TableData::data);}
898 
899 	int lendata;
900 	int lenxAxis;
901 	int lenyAxis;
902 
903 protected:
904 	bool areas;
905 };
906 
907 class TableDataVector : public TableData {
908 public:
TableDataVector()909 	TableDataVector() : pdata(0), pxAxis(0), pyAxis(0) {}
TableDataVector(Vector<double> & data,Vector<double> & xAxis,Vector<double> & yAxis,Interpolate _inter,bool _areas)910 	TableDataVector(Vector<double> &data, Vector<double> &xAxis, Vector<double> &yAxis,
911 			Interpolate _inter, bool _areas) {Init(data, xAxis, yAxis, _inter, _areas);}
Init(Vector<double> & data,Vector<double> & xAxis,Vector<double> & yAxis,Interpolate _inter,bool _areas)912 	void Init(Vector<double> &data, Vector<double> &xAxis, Vector<double> &yAxis,
913 					Interpolate _inter, bool _areas) {
914 		ASSERT(_areas ?  (data.GetCount() == (xAxis.GetCount() - 1)*(yAxis.GetCount() - 1)) : true);
915 		ASSERT(!_areas ? (data.GetCount() == xAxis.GetCount()*yAxis.GetCount()) : true);
916 		this->pdata = &data;
917 		this->lendata = data.GetCount();
918 		this->pxAxis = &xAxis;
919 		this->lenxAxis = xAxis.GetCount();
920 		this->pyAxis = &yAxis;
921 		this->lenyAxis = yAxis.GetCount();
922 		this->inter = _inter;
923 		this->areas = _areas;
924 	}
x(int id)925 	virtual inline double x(int id) 	{return (*pxAxis)[id];}
y(int id)926 	virtual inline double y(int id) 	{return (*pyAxis)[id];}
data(int id)927 	virtual inline double data(int id) 	{return (*pdata)[id];}
928 
929 private:
930 	Vector<double> *pdata;
931 	Vector<double> *pxAxis;
932 	Vector<double> *pyAxis;
933 };
934 
935 class TableDataCArray : public TableData {
936 public:
TableDataCArray()937 	TableDataCArray() : pdata(0), pxAxis(0), pyAxis(0) {}
TableDataCArray(double * data,int _lendata,double * xAxis,int _lenxAxis,double * yAxis,int _lenyAxis,Interpolate _inter,bool _areas)938 	TableDataCArray(double *data, int _lendata, double *xAxis, int _lenxAxis, double *yAxis, int _lenyAxis,
939 					Interpolate _inter, bool _areas) {Init(data, _lendata, xAxis, _lenxAxis, yAxis, _lenyAxis, _inter, _areas);}
Init(double * data,int _lendata,double * xAxis,int _lenxAxis,double * yAxis,int _lenyAxis,Interpolate _inter,bool _areas)940 	void Init(double *data, int _lendata, double *xAxis, int _lenxAxis, double *yAxis, int _lenyAxis,
941 					Interpolate _inter, bool _areas) {
942 		ASSERT(_areas ?  (_lendata == (_lenxAxis - 1)*(_lenyAxis - 1)) : true);
943 		ASSERT(!_areas ? (_lendata == _lenxAxis*_lenyAxis) : true);
944 		this->pdata = data;
945 		this->lendata = _lendata;
946 		this->pxAxis = xAxis;
947 		this->lenxAxis = _lenxAxis;
948 		this->pyAxis = yAxis;
949 		this->lenyAxis = _lenyAxis;
950 		this->inter = _inter;
951 		this->areas = _areas;
952 	}
x(int id)953 	virtual inline double x(int id) 	{return pxAxis[id];}
y(int id)954 	virtual inline double y(int id) 	{return pyAxis[id];}
data(int id)955 	virtual inline double data(int id) 	{return pdata[id];}
956 
957 private:
958 	double *pdata;
959 	double *pxAxis;
960 	double *pyAxis;
961 };
962 
963 
964 class ExplicitData : public DataSourceSurf {
965 public:
ExplicitData()966 	ExplicitData() {}
ExplicitData(Function<double (double x,double y)> _funz,double _minX,double _maxX,double _minY,double _maxY)967 	ExplicitData(Function<double (double x, double y)> _funz, double _minX, double _maxX, double _minY, double _maxY) {
968 		Init(_funz, _minX, _maxX, _minY, _maxY);
969 	}
970 	void Init(Function<double (double x, double y)> funz, double minX, double maxX, double minY, double maxY);
971 
z(double x,double y)972 	double z(double x, double y)	{return funz ? funz(x, y) : Null;}
973 
IsEmpty()974 	bool IsEmpty() 	{return funz;}
975 
MinX()976 	double MinX()	{return minX;}
MaxX()977 	double MaxX()	{return maxX;}
MinY()978 	double MinY()	{return minY;}
MaxY()979 	double MaxY()	{return maxY;}
MinZ()980 	double MinZ()	{return minZ;}
MaxZ()981 	double MaxZ()	{return maxZ;}
982 
983 private:
984 	double minX, maxX, minY, maxY, minZ, maxZ;
985 	Function<double (double x, double y)> funz;
986 };
987 
988 Vector<Pointf> Intersection(Vector<Pointf> &poly1, Vector<Pointf> &poly2);
989 void Simplify(Vector<Pointf> &poly, double dx, double dy);
990 
991 bool SavitzkyGolay_CheckParams(int nleft, int nright, int deg, int der);
992 Eigen::VectorXd SavitzkyGolay_Coeff(int nleft, int nright, int deg, int der);
993 
994 template<class T>
995 typename T::PlainObject Convolution(const Eigen::MatrixBase<T>& orig, const Eigen::MatrixBase<T>& kernel, const double factor = 1) {
996 	const Eigen::Index ksize = kernel.size();
997 
998 	ASSERT_(ksize % 2 != 0, "Only support odd sized kernels");
999 	ASSERT(orig.size() > ksize);
1000 
1001 	typename T::PlainObject dest(orig.size() - 2 * (ksize/2));
1002 
1003 	for (typename T::Index row = 0; row < dest.size(); ++row)
1004 	  	dest(row) = orig.segment(row, ksize).cwiseProduct(kernel).sum();
1005 	if (factor != 1)
1006 		dest *= factor;
1007 	return dest;
1008 }
1009 
1010 template<class T>
1011 typename T::PlainObject Convolution2D(const Eigen::MatrixBase<T>& orig, const Eigen::MatrixBase<T>& kernel, const double factor = 1) {
1012 	const Eigen::Index krows = kernel.rows();
1013 	const Eigen::Index kcols = kernel.cols();
1014 
1015 	ASSERT_(krows % 2 != 0, "Only support odd sized kernels (even rows)");
1016 	ASSERT_(kcols % 2 != 0, "Only support odd sized kernels (even cols)");
1017 	ASSERT(orig.rows() > krows);
1018 	ASSERT(orig.cols() > kcols);
1019 
1020 	typename T::PlainObject dest(orig.rows() - 2*(krows/2), orig.cols() - 2*(kcols/2));
1021 
1022 	for (typename T::Index row = 0; row < dest.rows(); ++row)
1023 		for (typename T::Index col = 0; col < dest.cols(); ++col)
1024 	  		dest(row, col) = orig.block(row, col, krows, kcols).cwiseProduct(kernel).sum();
1025 	if (factor != 1)
1026 		dest *= factor;
1027 	return dest;
1028 }
1029 
1030 //#include "deprecated.h"
1031 
1032 }
1033 
1034 #endif
1035