mglData
class have abstract predecessor class mglDataA
. Exactly the pointers to mglDataA
instances are used in all plotting functions and some of data processing functions. This was done for taking possibility to define yours own class, which will handle yours own data (for example, complex numbers, or differently organized data). And this new class will be almost the same as mglData
for plotting purposes.
However, the most of data processing functions will be slower as if you used mglData
instance. This is more or less understandable – I don’t know how data in yours particular class will be organized, and couldn’t optimize the these functions generally.
There are few virtual functions which must be provided in derived classes. This functions give:
GetNx
, GetNy
, GetNz
),
v
, dvx
, dvy
, dvz
),
Maximal
, Minimal
) – you can use provided functions (like mgl_data_max
and mgl_data_min
), but yours own realization can be more efficient,
vthr
) – you need this only if you want using MathGL’s data processing functions.
Let me, for example define class mglComplex
which will handle complex number and draw its amplitude or phase, depending on flag use_abs:
#include <complex> #include <mgl2/mgl.h> #define dual std::complex<double> class mglComplex : public mglDataA { public: long nx; ///< number of points in 1st dimensions ('x' dimension) long ny; ///< number of points in 2nd dimensions ('y' dimension) long nz; ///< number of points in 3d dimensions ('z' dimension) dual *a; ///< data array bool use_abs; ///< flag to use abs() or arg() inline mglComplex(long xx=1,long yy=1,long zz=1) { a=0; use_abs=true; Create(xx,yy,zz); } virtual ~mglComplex() { if(a) delete []a; } /// Get sizes inline long GetNx() const { return nx; } inline long GetNy() const { return ny; } inline long GetNz() const { return nz; } /// Create or recreate the array with specified size and fill it by zero inline void Create(long mx,long my=1,long mz=1) { nx=mx; ny=my; nz=mz; if(a) delete []a; a = new dual[nx*ny*nz]; } /// Get maximal value of the data inline mreal Maximal() const { return mgl_data_max(this); } /// Get minimal value of the data inline mreal Minimal() const { return mgl_data_min(this); } protected: inline mreal v(long i,long j=0,long k=0) const { return use_abs ? abs(a[i+nx*(j+ny*k)]) : arg(a[i+nx*(j+ny*k)]); } inline mreal vthr(long i) const { return use_abs ? abs(a[i]) : arg(a[i]); } inline mreal dvx(long i,long j=0,long k=0) const { long i0=i+nx*(j+ny*k); std::complex<double> res=i>0? (i<nx-1? (a[i0+1]-a[i0-1])/2.:a[i0]-a[i0-1]) : a[i0+1]-a[i0]; return use_abs? abs(res) : arg(res); } inline mreal dvy(long i,long j=0,long k=0) const { long i0=i+nx*(j+ny*k); std::complex<double> res=j>0? (j<ny-1? (a[i0+nx]-a[i0-nx])/2.:a[i0]-a[i0-nx]) : a[i0+nx]-a[i0]; return use_abs? abs(res) : arg(res); } inline mreal dvz(long i,long j=0,long k=0) const { long i0=i+nx*(j+ny*k), n=nx*ny; std::complex<double> res=k>0? (k<nz-1? (a[i0+n]-a[i0-n])/2.:a[i0]-a[i0-n]) : a[i0+n]-a[i0]; return use_abs? abs(res) : arg(res); } }; int main() { mglComplex dat(20); for(long i=0;i<20;i++) dat.a[i] = 3*exp(-0.05*(i-10)*(i-10))*dual(cos(M_PI*i*0.3), sin(M_PI*i*0.3)); mglGraph gr; gr.SetRange('y', -M_PI, M_PI); gr.Box(); gr.Plot(dat,"r","legend 'abs'"); dat.use_abs=false; gr.Plot(dat,"b","legend 'arg'"); gr.Legend(); gr.WritePNG("complex.png"); return 0; }