/*************************************************************************** * data.h is part of Math Graphic Library * Copyright (C) 2007-2016 Alexey Balakin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef _MGL_DATA_H_ #define _MGL_DATA_H_ #include "mgl2/data_cf.h" #include "mgl2/pde.h" //----------------------------------------------------------------------------- #include //----------------------------------------------------------------------------- mreal MGL_EXPORT mglLinear(const mreal *a, long nx, long ny, long nz, mreal x, mreal y, mreal z); mreal MGL_EXPORT mglSpline3(const mreal *a, long nx, long ny, long nz, mreal x, mreal y, mreal z,mreal *dx=0, mreal *dy=0, mreal *dz=0); mreal MGL_EXPORT mglSpline3s(const mreal *a, long nx, long ny, long nz, mreal x, mreal y, mreal z); std::string MGL_EXPORT mgl_data_to_string(HCDT d, long ns); //----------------------------------------------------------------------------- /// Class for working with data array class MGL_EXPORT mglData : public mglDataA { public: using mglDataA::Momentum; 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) mreal *a; ///< data array std::string id; ///< column (or slice) names bool link; ///< use external data (i.e. don't free it) /// Initiate by other mglData variable mglData(const mglData &d) { a=0; mgl_data_set(this,&d); } // NOTE: must be constructor for mglData& to exclude copy one #if MGL_HAVE_RVAL mglData(mglData &&d):nx(d.nx),ny(d.ny),nz(d.nz),a(d.a),id(d.id),link(d.link) { s=d.s; temp=d.temp; func=d.func; o=d.o; d.a=0; d.func=0; } #endif mglData(const mglDataA *d) { a=0; if(d) mgl_data_set(this, d); else mgl_data_create(this,1,1,1); } mglData(bool, mglData *d) // NOTE: Variable d will be deleted!!! { if(d) { nx=d->nx; ny=d->ny; nz=d->nz; a=d->a; d->a=0; temp=d->temp; func=d->func; o=d->o; s=d->s; id=d->id; link=d->link; delete d; } else { a=0; Create(1); } } /// Initiate by flat array mglData(int size, const float *d) { a=0; Set(d,size); } mglData(int rows, int cols, const float *d) { a=0; Set(d,cols,rows); } mglData(int size, const double *d) { a=0; Set(d,size); } mglData(int rows, int cols, const double *d) { a=0; Set(d,cols,rows); } mglData(const double *d, int size) { a=0; Set(d,size); } mglData(const double *d, int rows, int cols) { a=0; Set(d,cols,rows); } mglData(const float *d, int size) { a=0; Set(d,size); } mglData(const float *d, int rows, int cols) { a=0; Set(d,cols,rows); } /// Allocate memory and copy data from std::vector mglData(const std::vector &d) { a=0; Set(d); } mglData(const std::vector &d) { a=0; Set(d); } mglData(const std::vector &d) { a=0; Set(d); } /// Read data from file mglData(const char *fname) { a=0; Read(fname); } /// Allocate the memory for data array and initialize it zero mglData(long xx=1,long yy=1,long zz=1) { a=0; Create(xx,yy,zz); } /// Delete the array virtual ~mglData() { if(!link && a) delete []a; } /// Move all data from variable d, and delete this variable. inline void Move(mglData *d) // NOTE: Variable d will be deleted!!! { if(d && d->GetNN()>1) { bool l=link; mreal *b=a; nx=d->nx; ny=d->ny; nz=d->nz; a=d->a; d->a=b; temp=d->temp; func=d->func; o=d->o; s=d->s; id=d->id; link=d->link; d->link=l; delete d; } else if(d) { *this = d->a[0]; delete d; } } inline mreal GetVal(long i, long j=0, long k=0) const { return mgl_data_get_value(this,i,j,k);} inline void SetVal(mreal f, long i, long j=0, long k=0) { mgl_data_set_value(this,f,i,j,k); } /// Get sizes long GetNx() const { return nx; } long GetNy() const { return ny; } long GetNz() const { return nz; } /// Link external data array (don't delete it at exit) inline void Link(mreal *A, long NX, long NY=1, long NZ=1) { mgl_data_link(this,A,NX,NY,NZ); } inline void Link(mglData &d) { Link(d.a,d.nx,d.ny,d.nz); } /// Allocate memory and copy the data from the gsl_vector inline void Set(gsl_vector *m) { mgl_data_set_vector(this,m); } /// Allocate memory and copy the data from the gsl_matrix inline void Set(gsl_matrix *m) { mgl_data_set_matrix(this,m); } /// Allocate memory and copy the data from the (float *) array inline void Set(const float *A,long NX,long NY=1,long NZ=1) { mgl_data_set_float(this,A,NX,NY,NZ); } /// Allocate memory and copy the data from the (double *) array inline void Set(const double *A,long NX,long NY=1,long NZ=1) { mgl_data_set_double(this,A,NX,NY,NZ); } /// Allocate memory and copy the data from the (float **) array inline void Set(float const * const *A,long N1,long N2) { mgl_data_set_float2(this,A,N1,N2); } /// Allocate memory and copy the data from the (double **) array inline void Set(double const * const *A,long N1,long N2) { mgl_data_set_double2(this,A,N1,N2); } /// Allocate memory and copy the data from the (float ***) array inline void Set(float const * const * const *A,long N1,long N2,long N3) { mgl_data_set_float3(this,A,N1,N2,N3); } /// Allocate memory and copy the data from the (double ***) array inline void Set(double const * const * const *A,long N1,long N2,long N3) { mgl_data_set_double3(this,A,N1,N2,N3); } /// Allocate memory and scanf the data from the string inline void Set(const char *str,long NX,long NY=1,long NZ=1) { mgl_data_set_values(this,str,NX,NY,NZ); } /// Import data from abstract type inline void Set(HCDT dat) { mgl_data_set(this, dat); } inline void Set(const mglDataA &dat) { mgl_data_set(this, &dat); } /// Allocate memory and copy data from std::vector inline void Set(const std::vector &d) { if(d.size()>0) { Create(d.size()); for(long i=0;i &d) { if(d.size()>0) Set(&(d[0]),d.size()); else Create(1); } inline void Set(const std::vector &d) { if(d.size()>0) Set(&(d[0]),d.size()); else Create(1); } /// Allocate memory and set data from variable argument list of double values inline void SetList(long n, ...) { if(n<1) return; mgl_data_create(this,n,1,1); va_list vl; va_start(vl,n); for(long i=0;i0? (i0? (j0? (k(const mglDataA &b, const mglDataA &d) { return b.Minimal()>d.Minimal(); } //----------------------------------------------------------------------------- /// Integral data transformation (like Fourier 'f' or 'i', Hankel 'h' or None 'n') for amplitude and phase inline mglData mglTransformA(const mglDataA &am, const mglDataA &ph, const char *tr) { return mglData(true,mgl_transform_a(&am,&ph,tr)); } /// Integral data transformation (like Fourier 'f' or 'i', Hankel 'h' or None 'n') for real and imaginary parts inline mglData mglTransform(const mglDataA &re, const mglDataA &im, const char *tr) { return mglData(true,mgl_transform(&re,&im,tr)); } /// Apply Fourier transform for the data and save result into it inline void mglFourier(mglData &re, mglData &im, const char *dir) { mgl_data_fourier(&re,&im,dir); } /// Short time Fourier analysis for real and imaginary parts. Output is amplitude of partial Fourier (result will have size {dn, floor(nx/dn), ny} for dir='x' inline mglData mglSTFA(const mglDataA &re, const mglDataA &im, long dn, char dir='x') { return mglData(true, mgl_data_stfa(&re,&im,dn,dir)); } //----------------------------------------------------------------------------- /// Saves result of PDE solving (|u|^2) for "Hamiltonian" ham with initial conditions ini inline mglData mglPDE(HMGL gr, const char *ham, const mglDataA &ini_re, const mglDataA &ini_im, mreal dz=0.1, mreal k0=100,const char *opt="") { return mglData(true, mgl_pde_solve(gr,ham, &ini_re, &ini_im, dz, k0,opt)); } /// Saves result of PDE solving for "Hamiltonian" ham with initial conditions ini along a curve ray (must have nx>=7 - x,y,z,px,py,pz,tau or nx=5 - x,y,px,py,tau) inline mglData mglQO2d(const char *ham, const mglDataA &ini_re, const mglDataA &ini_im, const mglDataA &ray, mreal r=1, mreal k0=100) { return mglData(true, mgl_qo2d_solve(ham, &ini_re, &ini_im, &ray, r, k0, 0, 0)); } inline mglData mglQO2d(const char *ham, const mglDataA &ini_re, const mglDataA &ini_im, const mglDataA &ray, mglData &xx, mglData &yy, mreal r=1, mreal k0=100) { return mglData(true, mgl_qo2d_solve(ham, &ini_re, &ini_im, &ray, r, k0, &xx, &yy)); } /// Saves result of PDE solving for "Hamiltonian" ham with initial conditions ini along a curve ray (must have nx>=7 - x,y,z,px,py,pz,tau or nx=5 - x,y,px,py,tau) inline mglData mglQO3d(const char *ham, const mglDataA &ini_re, const mglDataA &ini_im, const mglDataA &ray, mreal r=1, mreal k0=100) { return mglData(true, mgl_qo3d_solve(ham, &ini_re, &ini_im, &ray, r, k0, 0, 0, 0)); } inline mglData mglQO3d(const char *ham, const mglDataA &ini_re, const mglDataA &ini_im, const mglDataA &ray, mglData &xx, mglData &yy, mglData &zz, mreal r=1, mreal k0=100) { return mglData(true, mgl_qo3d_solve(ham, &ini_re, &ini_im, &ray, r, k0, &xx, &yy, &zz)); } /// Finds ray with starting point r0, p0 (and prepares ray data for mglQO2d) inline mglData mglRay(const char *ham, mglPoint r0, mglPoint p0, mreal dt=0.1, mreal tmax=10) { return mglData(true, mgl_ray_trace(ham, r0.x, r0.y, r0.z, p0.x, p0.y, p0.z, dt, tmax)); } /// Saves result of ODE solving (|u|^2) for "Hamiltonian" ham with initial conditions ini inline mglData mglODE(const char *df, const char *var, const mglDataA &ini, mreal dt=0.1, mreal tmax=10) { return mglData(true, mgl_ode_solve_str(df,var, &ini, dt, tmax)); } //----------------------------------------------------------------------------- /// Get array as solution of tridiagonal system of equations a[i]*x[i-1]+b[i]*x[i]+c[i]*x[i+1]=d[i] /** String \a how may contain: * 'x', 'y', 'z' for solving along x-,y-,z-directions, or * 'h' for solving along hexagonal direction at x-y plain (need nx=ny), * 'c' for using periodical boundary conditions, * 'd' for diffraction/diffuse calculation. */ inline mglData mglTridMat(const mglDataA &A, const mglDataA &B, const mglDataA &C, const mglDataA &D, const char *how) { return mglData(true, mgl_data_tridmat(&A, &B, &C, &D, how)); } //----------------------------------------------------------------------------- /// Calculate Jacobian determinant for D{x(u,v), y(u,v)} = dx/du*dy/dv-dx/dv*dy/du inline mglData mglJacobian(const mglDataA &x, const mglDataA &y) { return mglData(true, mgl_jacobian_2d(&x, &y)); } /// Calculate Jacobian determinant for D{x(u,v,w), y(u,v,w), z(u,v,w)} inline mglData mglJacobian(const mglDataA &x, const mglDataA &y, const mglDataA &z) { return mglData(true, mgl_jacobian_3d(&x, &y, &z)); } /// Do something like Delone triangulation inline mglData mglTriangulation(const mglDataA &x, const mglDataA &y, const mglDataA &z) { return mglData(true,mgl_triangulation_3d(&x,&y,&z)); } inline mglData mglTriangulation(const mglDataA &x, const mglDataA &y) { return mglData(true,mgl_triangulation_2d(&x,&y)); } /// Get array which is n-th pairs {x[i],y[i]} for iterated function system (fractal) generated by A inline mglData mglIFS2d(const mglDataA &A, long n, long skip=20) { return mglData(true,mgl_data_ifs_2d(&A,n,skip)); } /// Get array which is n-th points {x[i],y[i],z[i]} for iterated function system (fractal) generated by A inline mglData mglIFS3d(const mglDataA &A, long n, long skip=20) { return mglData(true,mgl_data_ifs_3d(&A,n,skip)); } /// Get array which is n-th points {x[i],y[i],z[i]} for iterated function system (fractal) defined in *.ifs file 'fname' and named as 'name' inline mglData mglIFSfile(const char *fname, const char *name, long n, long skip=20) { return mglData(true,mgl_data_ifs_file(fname,name,n,skip)); } /// Get array which is n-th pairs {x[i],y[i]} for flame fractal generated by A with functions F /// Get array which is n-th pairs {x[i],y[i]} for Flame fractal generated by A with functions F /** NOTE: A.nx must be >= 7 and F.nx >= 2 and F.nz=A.ny. * F[0,i,j] denote function id. F[1,i,j] give function weight, F(2:5,i,j) provide function parameters. * Resulting point is {xnew,ynew} = sum_i F[1,i,j]*F[0,i,j]{IFS2d(A[j]){x,y}}. */ inline mglData mglFlame2d(const mglDataA &A, const mglDataA &F, long n, long skip=20) { return mglData(true,mgl_data_flame_2d(&A,&F,n,skip)); } //----------------------------------------------------------------------------- /// Get sub-array of the data with given fixed indexes inline mglData mglSubData(const mglDataA &dat, long xx, long yy=-1, long zz=-1) { return mglData(true,mgl_data_subdata(&dat,xx,yy,zz)); } inline mglData mglSubData(const mglDataA &dat, const mglDataA &xx, const mglDataA &yy, const mglDataA &zz) { return mglData(true,mgl_data_subdata_ext(&dat,&xx,&yy,&zz)); } inline mglData mglSubData(const mglDataA &dat, const mglDataA &xx, const mglDataA &yy) { return mglData(true,mgl_data_subdata_ext(&dat,&xx,&yy,0)); } inline mglData mglSubData(const mglDataA &dat, const mglDataA &xx) { return mglData(true,mgl_data_subdata_ext(&dat,&xx,0,0)); } //----------------------------------------------------------------------------- /// Prepare coefficients for global spline interpolation inline mglData mglGSplineInit(const mglDataA &xdat, const mglDataA &ydat) { return mglData(true,mgl_gspline_init(&xdat, &ydat)); } /// Evaluate global spline (and its derivatives d1, d2 if not NULL) using prepared coefficients \a coef inline mreal mglGSpline(const mglDataA &coef, mreal dx, mreal *d1=0, mreal *d2=0) { return mgl_gspline(&coef, dx, d1,d2); } //----------------------------------------------------------------------------- /// Wrapper class for expression evaluating class MGL_EXPORT mglExpr { HMEX ex; mglExpr(const mglExpr &){} // copying is not allowed const mglExpr &operator=(const mglExpr &t){return t;} // copying is not allowed public: mglExpr(const char *expr) { ex = mgl_create_expr(expr); } #if MGL_HAVE_RVAL mglExpr(mglExpr &&d):ex(d.ex) { d.ex=0; } #endif ~mglExpr() { mgl_delete_expr(ex); } /// Return value of expression for given x,y,z variables inline double Eval(double x, double y=0, double z=0) { return mgl_expr_eval(ex,x,y,z); } /// Return value of expression differentiation over variable dir for given x,y,z variables inline double Diff(char dir, double x, double y=0, double z=0) { return mgl_expr_diff(ex,dir, x,y,z); } #ifndef SWIG /// Return value of expression for given variables inline double Eval(mreal var[26]) { return mgl_expr_eval_v(ex,var); } /// Return value of expression differentiation over variable dir for given variables inline double Diff(char dir, mreal var[26]) { return mgl_expr_diff_v(ex,dir, var); } #endif }; //----------------------------------------------------------------------------- /// Class which present variable as data array class MGL_EXPORT mglDataV : public mglDataA { 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) mreal di, dj, dk, a0; public: mglDataV(long xx=1,long yy=1,long zz=1,mreal x1=0,mreal x2=mglNaN,char dir='x'):nx(xx),ny(yy),nz(zz) { Fill(x1,x2,dir); } mglDataV(const mglDataV &d):nx(d.nx),ny(d.ny),nz(d.nz),di(d.di),dj(d.dj),dk(d.dk),a0(d.a0) {} #if MGL_HAVE_RVAL mglDataV(mglDataV &&d):nx(d.nx),ny(d.ny),nz(d.nz),di(d.di),dj(d.dj),dk(d.dk),a0(d.a0) { s=d.s; temp=d.temp; func=d.func; o=d.o; d.func=0; } #endif virtual ~mglDataV() {} /// Get sizes long GetNx() const { return nx; } long GetNy() const { return ny; } 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) { di=mx>1?di*(nx-1)/(mx-1):0; dj=my>1?dj*(ny-1)/(my-1):0; dk=mz>1?dk*(nz-1)/(mz-1):0; nx=mx; ny=my; nz=mz; } /// For going throw all elements inline void All() { di=dj=dk=1; a0=0; } /// Equidistantly fill the data to range [x1,x2] in direction dir inline void Fill(mreal x1,mreal x2=mglNaN,char dir='x') { di=dj=dk=0; a0=x1; if(mgl_isnum(x2)) { if(dir=='x' && nx>1) di=(x2-x1)/(nx-1); if(dir=='y' && ny>1) dj=(x2-x1)/(ny-1); if(dir=='z' && nz>1) dk=(x2-x1)/(nz-1); } } mreal Maximal() const { return a0+mgl_max(mgl_max(di*(nx-1),dj*(ny-1)),mgl_max(dk*(nz-1),0)); } mreal Minimal() const { return a0+mgl_min(mgl_min(di*(nx-1),dj*(ny-1)),mgl_min(dk*(nz-1),0)); } /// Copy data from other mglDataV variable inline const mglDataV &operator=(const mglDataV &d) { nx=d.nx; ny=d.ny; nz=d.nz; a0=d.a0; di=d.di; dj=d.dj; dk=d.dk; return d; } inline mreal operator=(mreal val) { di=dj=dk=0; a0=val; return val; } /// Get the interpolated value and its derivatives in given data cell without border checking mreal valueD(mreal x,mreal y=0,mreal z=0,mreal *dx=0,mreal *dy=0,mreal *dz=0) const { if(dx) *dx=di; if(dy) *dy=dj; if(dz) *dz=dk; return a0+di*x+dj*y+dk*z; } /// Get the interpolated value in given data cell without border checking mreal value(mreal x,mreal y=0,mreal z=0) const { return a0+di*x+dj*y+dk*z; } mreal v(long i,long j=0,long k=0) const { return a0+di*i+dj*j+dk*k; } mreal vthr(long ii) const { register long i=ii%nx, j=(ii/nx)%ny, k=ii/(nx*ny); return a0+di*i+dj*j+dk*k; } // add for speeding up !!! mreal dvx(long ,long =0,long =0) const { return di; } mreal dvy(long ,long =0,long =0) const { return dj; } mreal dvz(long ,long =0,long =0) const { return dk; } }; //----------------------------------------------------------------------------- /// Class which present FFT frequency as data array class MGL_EXPORT mglDataW : public mglDataA { 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) mreal di, dj, dk; public: mglDataW(long xx=1,long yy=1,long zz=1,mreal dp=0,char dir='x'):nx(xx),ny(yy),nz(zz) { Freq(dp,dir); } mglDataW(const mglDataW &d):nx(d.nx),ny(d.ny),nz(d.nz),di(d.di),dj(d.dj),dk(d.dk) {} #if MGL_HAVE_RVAL mglDataW(mglDataW &&d):nx(d.nx),ny(d.ny),nz(d.nz),di(d.di),dj(d.dj),dk(d.dk) { s=d.s; temp=d.temp; func=d.func; o=d.o; d.func=0; } #endif virtual ~mglDataW() {} /// Get sizes long GetNx() const { return nx; } long GetNy() const { return ny; } 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; } /// For going throw all elements inline void All() { di=dj=dk=1; } /// Equidistantly fill the data to range [x1,x2] in direction dir inline void Freq(mreal dp,char dir='x') { di=dj=dk=0; if(dir=='x') di=dp; if(dir=='y') dj=dp; if(dir=='z') dk=dp; } mreal Maximal() const { return mgl_max(mgl_max(di*(nx-1),dj*(ny-1)),mgl_max(dk*(nz-1),0)); } mreal Minimal() const { return mgl_min(mgl_min(di*(nx-1),dj*(ny-1)),mgl_min(dk*(nz-1),0)); } /// Copy data from other mglDataV variable inline const mglDataW &operator=(const mglDataW &d) { nx=d.nx; ny=d.ny; nz=d.nz; di=d.di; dj=d.dj; dk=d.dk; return d; } /// Get the interpolated value and its derivatives in given data cell without border checking mreal valueD(mreal x,mreal y=0,mreal z=0,mreal *dx=0,mreal *dy=0,mreal *dz=0) const { if(dx) *dx=di; if(dy) *dy=dj; if(dz) *dz=dk; return di*(x1?(v2.x-v1.x)/(nx-1):0; dy = ny>1?(v2.y-v1.y)/(ny-1):0; dz = nz>1?(v2.z-v1.z)/(nz-1):0; } mreal (*dfunc)(mreal i, mreal j, mreal k, void *par); void *par; public: mglDataF(long xx=1,long yy=1,long zz=1):nx(xx),ny(yy),nz(zz), dfunc(0),par(0) { ex=0; v2.Set(1,1,1); setD(); } mglDataF(const mglDataF &d) : nx(d.nx), ny(d.ny), nz(d.nz), str(d.str), v1(d.v1), v2(d.v2), dx(d.dx),dy(d.dy),dz(d.dz), dfunc(d.dfunc),par(d.par) { ex = mgl_create_expr(str.c_str()); } #if MGL_HAVE_RVAL mglDataF(mglDataF &&d):nx(d.nx),ny(d.ny),nz(d.nz), str(d.str), v1(d.v1),v2(d.v2), ex(d.ex), dx(d.dx),dy(d.dy),dz(d.dz), dfunc(d.dfunc),par(d.par) { s=d.s; temp=d.temp; func=d.func; o=d.o; d.ex=0; d.func=0; } #endif virtual ~mglDataF() { mgl_delete_expr(ex); } /// Get sizes long GetNx() const { return nx; } long GetNy() const { return ny; } 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; setD(); } inline void SetRanges(mglPoint p1, mglPoint p2) { v1=p1; v2=p2; setD(); } /// Set formula to be used as dfunction inline void SetFormula(const char *eq) { mgl_delete_expr(ex); dfunc=0; par=0; if(eq && *eq) { ex = mgl_create_expr(eq); str=eq; } else { ex=0; str=""; } } /// Set function and coordinates range [r1,r2] inline void SetFunc(mreal (*f)(mreal,mreal,mreal,void*), void *p=NULL) { mgl_delete_expr(ex); ex=0; dfunc=f; par=p; } /// Get the interpolated value and its derivatives in given data cell without border checking mreal valueD(mreal i,mreal j=0,mreal k=0, mreal *di=0,mreal *dj=0,mreal *dk=0) const { mreal res=0, x=v1.x+dx*i, y=v1.y+dy*j, z=v1.z+dz*k; if(di) *di = 0; if(dj) *dj = 0; if(dk) *dk = 0; if(dfunc) { res = dfunc(x,y,z, par); if(di) *di = dfunc(x+dx,y,z, par)-res; if(dj) *dj = dfunc(x,y+dy,z, par)-res; if(dk) *dk = dfunc(x,y,z+dz, par)-res; } else if(ex) { if(di) *di = mgl_expr_diff(ex,'x',x,y,z)*dx; if(dj) *dj = mgl_expr_diff(ex,'y',x,y,z)*dy; if(dk) *dk = mgl_expr_diff(ex,'z',x,y,z)*dz; res = mgl_expr_eval(ex,x,y,z); } return res; } /// Get the interpolated value in given data cell without border checking mreal value(mreal i,mreal j=0,mreal k=0) const { mreal res=0, x=v1.x+dx*i, y=v1.y+dy*j, z=v1.z+dz*k; if(dfunc) res = dfunc(x,y,z, par); else if(ex) res = mgl_expr_eval(ex,x,y,z); return res; } /// Copy data from other mglDataV variable inline const mglDataF &operator=(const mglDataF &d) { nx=d.nx; ny=d.ny; nz=d.nz; v1=d.v1; v2=d.v2; setD(); str=d.str; ex = mgl_create_expr(str.c_str()); dfunc=d.dfunc; par=d.par; return d; } /// Get the value in given cell of the data without border checking mreal v(long i,long j=0,long k=0) const { mreal res=0, x=v1.x+dx*i, y=v1.y+dy*j, z=v1.z+dz*k; if(dfunc) res = dfunc(x,y,z, par); else if(ex) res = mgl_expr_eval(ex,x,y,z); return res; } mreal vthr(long i) const { mreal res=0, x=v1.x+dx*(i%nx), y=v1.y+dy*((i/nx)%ny), z=v1.z+dz*(i/(nx*ny)); if(dfunc) res = dfunc(x,y,z, par); else if(ex) res = mgl_expr_eval(ex,x,y,z); return res; } // add for speeding up !!! mreal dvx(long i,long j=0,long k=0) const { mreal res=0, x=v1.x+dx*i, y=v1.y+dy*j, z=v1.z+dz*k; if(dfunc) res = dfunc(x+dx,y,z, par)-dfunc(x,y,z, par); else if(ex) res = mgl_expr_eval(ex,x+dx,y,z)-mgl_expr_eval(ex,x,y,z); return res; } mreal dvy(long i,long j=0,long k=0) const { mreal res=0, x=v1.x+dx*i, y=v1.y+dy*j, z=v1.z+dz*k; if(dfunc) res = dfunc(x,y+dy,z, par)-dfunc(x,y,z, par); else if(ex) res = mgl_expr_eval(ex,x,y+dy,z)-mgl_expr_eval(ex,x,y,z); return res; } mreal dvz(long i,long j=0,long k=0) const { mreal res=0, x=v1.x+dx*i, y=v1.y+dy*j, z=v1.z+dz*k; if(dfunc) res = dfunc(x,y,z+dz, par)-dfunc(x,y,z, par); else if(ex) res = mgl_expr_eval(ex,x,y,z+dz)-mgl_expr_eval(ex,x,y,z); return res; } }; //----------------------------------------------------------------------------- /// Class which present variable as data array class MGL_EXPORT mglDataT : public mglDataA { const mglDataA &dat; long ind; public: mglDataT(const mglDataT &d) : dat(d.dat), ind(d.ind) { s = d.s; } mglDataT(const mglDataA &d, long col=0) : dat(d), ind(col) {} #if MGL_HAVE_RVAL mglDataT(mglDataT &&d):dat(d.dat),ind(d.ind) { s=d.s; temp=d.temp; func=d.func; o=d.o; d.func=0; } #endif virtual ~mglDataT() {} /// Get sizes long GetNx() const { return dat.GetNy(); } long GetNy() const { return dat.GetNz(); } long GetNz() const { return 1; } mreal Maximal() const { return mglSubData(dat,ind).Maximal(); } mreal Minimal() const { return mglSubData(dat,ind).Minimal(); } inline void SetInd(long i, const wchar_t *name) { ind = i; s = name; } inline void SetInd(long i, wchar_t name) { ind = i; s = name; } /// Get the interpolated value and its derivatives in given data cell without border checking mreal valueD(mreal x,mreal y=0,mreal =0,mreal *dx=0,mreal *dy=0,mreal *dz=0) const { if(dz) *dz=0; return dat.valueD(ind,x,y,0,dx,dy); } /// Get the interpolated value in given data cell without border checking mreal value(mreal x,mreal y=0,mreal =0) const { return dat.value(ind,x,y); } /// Get the value in given cell of the data without border checking mreal v(long i,long j=0,long =0) const { return dat.v(ind,i,j); } mreal vthr(long i) const { return dat.vthr(ind+dat.GetNx()*i); } // add for speeding up !!! mreal dvx(long i,long j=0,long =0) const { return dat.dvy(ind,i,j); } mreal dvy(long i,long j=0,long =0) const { return dat.dvz(ind,i,j); } mreal dvz(long ,long =0,long =0) const { return 0; } }; //----------------------------------------------------------------------------- class MGL_EXPORT mglDataR : public mglDataA { const mglDataA &dat; long ind; public: mglDataR(const mglDataR &d) : dat(d.dat), ind(d.ind) { s = d.s; } mglDataR(const mglDataA &d, long row=0) : dat(d), ind(row) {} #if MGL_HAVE_RVAL mglDataR(mglDataR &&d):dat(d.dat),ind(d.ind) { s=d.s; temp=d.temp; func=d.func; o=d.o; d.func=0; } #endif virtual ~mglDataR() {} /// Get sizes long GetNx() const { return dat.GetNx(); } long GetNy() const { return 1; } long GetNz() const { return 1; } mreal Maximal() const { return mglSubData(dat,-1,ind).Maximal(); } mreal Minimal() const { return mglSubData(dat,-1,ind).Minimal(); } inline void SetInd(long i, const wchar_t *name) { ind = i; s = name; } inline void SetInd(long i, wchar_t name) { ind = i; s = name; } /// Get the interpolated value and its derivatives in given data cell without border checking mreal valueD(mreal x,mreal =0,mreal =0,mreal *dx=0,mreal *dy=0,mreal *dz=0) const { if(dy) *dy=0; if(dz) *dz=0; return dat.valueD(x,ind,0,dx); } /// Get the interpolated value in given data cell without border checking mreal value(mreal x,mreal =0,mreal =0) const { return dat.value(x,ind,0); } /// Get the value in given cell of the data without border checking mreal v(long i,long =0,long =0) const { return dat.v(i,ind,0); } mreal vthr(long i) const { return dat.vthr(i+dat.GetNx()*ind); } // add for speeding up !!! mreal dvx(long i,long =0,long =0) const { return dat.dvx(i,ind,0); } mreal dvy(long ,long =0,long =0) const { return 0; } mreal dvz(long ,long =0,long =0) const { return 0; } }; //----------------------------------------------------------------------------- /// Class for replacement of std::vector class MGL_EXPORT mglDataS : public mglDataA { public: std::vector dat; mglDataS(const mglDataS &st) : dat(st.dat) {} mglDataS(const std::vector &d) : dat(d) {} mglDataS(size_t s=1) { dat.resize(s); } ~mglDataS() {} inline void reserve(size_t num) { dat.reserve(num); } inline void clear() { dat.clear(); } inline double operator[](size_t i) { return dat[i]; } inline void push_back(double t) { dat.push_back(t); } inline size_t size() const { return dat.size(); } const mglDataS &operator=(const mglDataS &st) { dat = st.dat; return st; } const std::vector &operator=(const std::vector &st) { dat = st; return st; } /// Get the interpolated value and its derivatives in given data cell without border checking mreal valueD(mreal x,mreal =0,mreal =0,mreal *dx=0,mreal *dy=0,mreal *dz=0) const { return mglSpline3(dat.data(),dat.size(),1,1,x,0,0,dx,dy,dz); } /// Get the interpolated value in given data cell without border checking mreal value(mreal x,mreal =0,mreal =0) const { return mglSpline3s(dat.data(),dat.size(),1,1,x,0,0); } mreal v(long i,long =0,long =0) const { return dat[i]; } mreal vthr(long i) const { return dat[i]; }; long GetNx() const { return dat.size(); } long GetNy() const { return 1; } long GetNz() const { return 1; } mreal dvx(long i,long =0,long =0) const { return i>0? (i