/*************************************************************************** * datac.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_DATAC_H_ #define _MGL_DATAC_H_ #include "mgl2/data.h" #include "mgl2/datac_cf.h" //----------------------------------------------------------------------------- #include #include //----------------------------------------------------------------------------- #ifndef SWIG dual MGL_EXPORT mglLinearC(const dual *a, long nx, long ny, long nz, mreal x, mreal y, mreal z); dual MGL_EXPORT mglSpline3C(const dual *a, long nx, long ny, long nz, mreal x, mreal y, mreal z,dual *dx=0, dual *dy=0, dual *dz=0); dual MGL_EXPORT mglSpline3Cs(const dual *a, long nx, long ny, long nz, mreal x, mreal y, mreal z); //----------------------------------------------------------------------------- /// Class for working with complex data array class MGL_EXPORT mglDataC : 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) dual *a; ///< data array std::string id; ///< column (or slice) names bool link; ///< use external data (i.e. don't free it) /// Initiate by other mglDataC variable mglDataC(const mglDataC &d) { a=0; mgl_datac_set(this,&d); } // NOTE: must be constructor for mglDataC& to exclude copy one mglDataC(const mglDataA &d) { a=0; mgl_datac_set(this,&d); } #if MGL_HAVE_RVAL mglDataC(mglDataC &&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 mglDataC(const mglDataA &re, const mglDataA &im) { a=0; mgl_datac_set_ri(this,&re,&im); } mglDataC(HCDT d) { a=0; mgl_datac_set(this, d); } mglDataC(HCDT re, HCDT im) { a=0; mgl_datac_set_ri(this, re, im); } mglDataC(bool, mglDataC *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 mglDataC(int size, const dual *d) { a=0; Set(d,size); } mglDataC(int rows, int cols, const dual *d) { a=0; Set(d,cols,rows); } mglDataC(int size, const double *d) { a=0; Set(d,size); } mglDataC(int rows, int cols, const double *d) { a=0; Set(d,cols,rows); } mglDataC(int size, const float *d) { a=0; Set(d,size); } mglDataC(int rows, int cols, const float *d) { a=0; Set(d,cols,rows); } mglDataC(const dual *d, int size) { a=0; Set(d,size); } mglDataC(const dual *d, int rows, int cols) { a=0; Set(d,cols,rows); } mglDataC(const double *d, int size) { a=0; Set(d,size); } mglDataC(const double *d, int rows, int cols) { a=0; Set(d,cols,rows); } mglDataC(const float *d, int size) { a=0; Set(d,size); } mglDataC(const float *d, int rows, int cols) { a=0; Set(d,cols,rows); } /// Allocate memory and copy data from std::vector mglDataC(const std::vector &d) { a=0; Set(d); } mglDataC(const std::vector &d) { a=0; Set(d); } mglDataC(const std::vector &d) { a=0; Set(d); } mglDataC(const std::vector > &d) { a=0; Set(d); } mglDataC(const std::vector > &d) { a=0; Set(d); } /// Read data from file mglDataC(const char *fname) { a=0; Read(fname); } /// Allocate the memory for data array and initialize it zero mglDataC(long xx=1,long yy=1,long zz=1) { a=0; Create(xx,yy,zz); } /// Delete the array virtual ~mglDataC() { if(!link && a) delete []a; } /// Move all data from variable d, and delete this variable. inline void Move(mglDataC *d) // NOTE: Variable d will be deleted!!! { if(d && d->GetNN()>1) { bool l=link; dual *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 dual GetVal(long i, long j=0, long k=0) const { return mgl_datac_get_value(this,i,j,k);} inline void SetVal(dual f, long i, long j=0, long k=0) { mgl_datac_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(dual *A, long NX, long NY=1, long NZ=1) { mgl_datac_link(this,A,NX,NY,NZ); } inline void Link(mglDataC &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_datac_set_vector(this,m); } /// Allocate memory and copy the data from the gsl_matrix inline void Set(gsl_matrix *m) { mgl_datac_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_datac_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_datac_set_double(this,A,NX,NY,NZ); } /// Allocate memory and copy the data from the (complex *) array inline void Set(const dual *A,long NX,long NY=1,long NZ=1) { mgl_datac_set_complex(this,A,NX,NY,NZ); } /// Allocate memory and scanf the data from the string inline void Set(const char *str,long NX,long NY=1,long NZ=1) { mgl_datac_set_values(this,str,NX,NY,NZ); } /// Import data from abstract type inline void Set(HCDT dat) { mgl_datac_set(this, dat); } inline void Set(const mglDataA &dat) { mgl_datac_set(this, &dat); } inline void Set(const mglDataA &re, const mglDataA &im) { mgl_datac_set_ri(this, &re, &im); } inline void Set(HCDT re, HCDT im) { mgl_datac_set_ri(this, re, im); } inline void SetAmpl(const mglDataA &l, const mglDataA &phase) { mgl_datac_set_ap(this, &l, &phase); } /// 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(&(a[0]),d.size()); else Create(1); } inline void Set(const std::vector &d) { if(d.size()>0) Set(&(a[0]),d.size()); else Create(1); } inline void Set(const std::vector > &d) { if(d.size()>0) { Create(d.size()); for(long i=0;i > &d) { if(d.size()>0) { Create(d.size()); for(long i=0;i1?nx-1:1; dif.y/=ny>1?ny-1:1; dif.z/=nz>1?nz-1:1; return val; } /// Return an approximated x-value (root) when dat(x) = val inline mreal Solve(mreal val, bool use_spline=true, long i0=0) const { return mgl_data_solve_1d(this, val, use_spline, i0); } /// Return an approximated value (root) when dat(x) = val inline mglData Solve(mreal val, char dir, bool norm=true) const { return mglData(true,mgl_data_solve(this, val, dir, 0, norm)); } inline mglData Solve(mreal val, char dir, const mglData &i0, bool norm=true) const { return mglData(true,mgl_data_solve(this, val, dir, &i0, norm)); } /// Copy data from other mglDataA variable inline const mglDataA &operator=(const mglDataA &d) { if(this!=&d) Set(&d); return d; } inline const mglDataC &operator=(const mglDataC &d) { if(this!=&d) Set(&d); return d; } inline dual operator=(dual val) { #pragma omp parallel for for(long i=0;i0? abs(i0? abs(j0? abs(k=7 - x,y,z,px,py,pz,tau or nx=5 - x,y,px,py,tau) inline mglDataC mglQO2dc(const char *ham, const mglDataA &ini_re, const mglDataA &ini_im, const mglDataA &ray, mreal r=1, mreal k0=100) { return mglDataC(true, mgl_qo2d_solve_c(ham, &ini_re, &ini_im, &ray, r, k0, 0, 0)); } inline mglDataC mglQO2dc(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 mglDataC(true, mgl_qo2d_solve_c(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 mglDataC mglQO3dc(const char *ham, const mglDataA &ini_re, const mglDataA &ini_im, const mglDataA &ray, mreal r=1, mreal k0=100) { return mglDataC(true, mgl_qo3d_solve_c(ham, &ini_re, &ini_im, &ray, r, k0, 0, 0, 0)); } inline mglDataC mglQO3dc(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 mglDataC(true, mgl_qo3d_solve_c(ham, &ini_re, &ini_im, &ray, r, k0, &xx, &yy, &zz)); } //----------------------------------------------------------------------------- /// 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 mglDataC mglTridMatC(const mglDataA &A, const mglDataA &B, const mglDataA &C, const mglDataC &D, const char *how) { return mglDataC(true, mgl_datac_tridmat(&A, &B, &C, &D, how)); } //----------------------------------------------------------------------------- /// Get sub-array of the data with given fixed indexes inline mglDataC mglSubDataC(const mglDataA &dat, long xx, long yy=-1, long zz=-1) { return mglDataC(true,mgl_datac_subdata(&dat,xx,yy,zz)); } inline mglDataC mglSubDataC(const mglDataA &dat, const mglDataA &xx, const mglDataA &yy, const mglDataA &zz) { return mglDataC(true,mgl_datac_subdata_ext(&dat,&xx,&yy,&zz)); } inline mglDataC mglSubDataC(const mglDataA &dat, const mglDataA &xx, const mglDataA &yy) { return mglDataC(true,mgl_datac_subdata_ext(&dat,&xx,&yy,0)); } inline mglDataC mglSubDataC(const mglDataA &dat, const mglDataA &xx) { return mglDataC(true,mgl_datac_subdata_ext(&dat,&xx,0,0)); } //----------------------------------------------------------------------------- /// Prepare coefficients for global spline interpolation inline mglDataC mglGSplineCInit(const mglDataA &xdat, const mglDataA &ydat) { return mglDataC(true,mgl_gsplinec_init(&xdat, &ydat)); } /// Evaluate global spline (and its derivatives d1, d2 if not NULL) using prepared coefficients \a coef inline dual mglGSplineC(const mglDataA &coef, mreal dx, dual *d1=0, dual *d2=0) { return mgl_gsplinec(&coef, dx, d1,d2); } //----------------------------------------------------------------------------- #define _DN_(a) ((mglDataC *)*(a)) #define _DC_ ((mglDataC *)*d) //----------------------------------------------------------------------------- #ifndef SWIG /// Wrapper class for complex expression evaluating class MGL_EXPORT mglExprC { HAEX ex; mglExprC(const mglExprC &){} // copying is not allowed const mglExprC &operator=(const mglExprC &t){return t;} // copying is not allowed public: mglExprC(const char *expr) { ex = mgl_create_cexpr(expr); } ~mglExprC() { mgl_delete_cexpr(ex); } /// Return value of expression for given x,y,z variables inline dual Eval(dual x, dual y=0, dual z=0) { return mgl_cexpr_eval(ex,x,y,z); } /// Return value of expression for given x,y,z,u,v,w variables inline dual Eval(dual x, dual y, dual z, dual u, dual v, dual w) { dual var[26]; var['x'-'a']=x; var['y'-'a']=y; var['z'-'a']=z; var['u'-'a']=u; var['v'-'a']=v; var['w'-'a']=w; return mgl_cexpr_eval_v(ex,var); } /// Return value of expression for given variables inline dual Eval(dual var[26]) { return mgl_cexpr_eval_v(ex,var); } }; #endif //----------------------------------------------------------------------------- #endif #endif