1 /***************************************************************************
2 * data_io.cpp is part of Math Graphic Library
3 * Copyright (C) 2007-2016 Alexey Balakin <mathgl.abalakin@gmail.ru> *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU Lesser General Public License as *
7 * published by the Free Software Foundation; either version 3 of the *
8 * License, or (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU Lesser General Public *
16 * License along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
20 #include <ctype.h>
21
22 #ifndef WIN32
23 #include <glob.h>
24 #endif
25
26 #include "mgl2/data.h"
27 #include "mgl2/datac.h"
28 #include "mgl2/eval.h"
29 #include "mgl2/thread.h"
30
31 #if MGL_HAVE_HDF5
32 //#define H5_NO_DEPRECATED_SYMBOLS
33 #define H5_USE_16_API
34 #include <hdf5.h>
35 #endif
36 #if MGL_HAVE_HDF4
37 #define intf hdf4_intf
38 #include <mfhdf.h>
39 #undef intf
40 #endif
41
isn(char ch)42 inline bool isn(char ch) {return ch=='\n';}
43 //-----------------------------------------------------------------------------
mgl_create_data()44 HMDT MGL_EXPORT mgl_create_data() { return new mglData; }
mgl_create_data_size(long nx,long ny,long nz)45 HMDT MGL_EXPORT mgl_create_data_size(long nx, long ny, long nz){ return new mglData(nx,ny,nz); }
mgl_create_data_file(const char * fname)46 HMDT MGL_EXPORT mgl_create_data_file(const char *fname) { return new mglData(fname); }
mgl_delete_data(HMDT d)47 void MGL_EXPORT mgl_delete_data(HMDT d) { if(d) delete d; }
48 //-----------------------------------------------------------------------------
mgl_create_data_()49 uintptr_t MGL_EXPORT mgl_create_data_()
50 { return uintptr_t(mgl_create_data()); }
mgl_create_data_size_(int * nx,int * ny,int * nz)51 uintptr_t MGL_EXPORT mgl_create_data_size_(int *nx, int *ny, int *nz)
52 { return uintptr_t(mgl_create_data_size(*nx,*ny,*nz)); }
mgl_create_data_file_(const char * fname,int l)53 uintptr_t MGL_EXPORT mgl_create_data_file_(const char *fname,int l)
54 { char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0;
55 uintptr_t r = uintptr_t(mgl_create_data_file(s)); delete []s; return r; }
mgl_delete_data_(uintptr_t * d)56 void MGL_EXPORT mgl_delete_data_(uintptr_t *d)
57 { mgl_delete_data(_DT_); }
58 //-----------------------------------------------------------------------------
mglFromStr(HMDT d,char * buf,long NX,long NY,long NZ)59 void mglFromStr(HMDT d,char *buf,long NX,long NY,long NZ)
60 {
61 if(NX<1 || NY <1 || NZ<1) return;
62 mgl_data_create(d, NX,NY,NZ);
63 const std::string loc = setlocale(LC_NUMERIC, "C");
64 std::vector<char *> lines;
65 std::vector<std::vector<mreal> > numbs;
66 while(*buf && *buf<=' ') buf++;
67 lines.push_back(buf);
68 for(char *s=buf; *s; s++) if(isn(*s))
69 { lines.push_back(s+1); *s = 0; s++; }
70 numbs.resize(lines.size());
71 long nl = long(lines.size());
72 #pragma omp parallel for
73 for(long k=0;k<nl;k++)
74 {
75 char *b = lines[k];
76 long nb = strlen(b);
77 for(long j=0;j<nb;j++)
78 {
79 while(j<nb && b[j]<=' ') j++; // skip first spaces
80 if(j>=nb) break;
81 if(b[j]=='#')
82 {
83 std::string id;
84 if(j<nb-1 && b[j+1]=='#') for(long i=j+2;i<nb;i++)
85 if(b[i]>='a' && b[i]<='z') id.push_back(b[i]);
86 d->SetColumnId(id.c_str());
87 break;
88 }
89 const char *s=b+j;
90 while(j<nb && b[j]>' ' && b[j]!=',' && b[j]!=';') j++;
91 b[j]=0;
92 numbs[k].push_back(strstr(s,"NAN")?NAN:atof(s));
93 }
94 }
95 long i=0, n=NX*NY*NZ;
96 for(long k=0;k<nl && i<n;k++)
97 {
98 const std::vector<mreal> &vals = numbs[k];
99 long c = vals.size();
100 if(c>n-i) c = n-i;
101 memcpy(d->a+i,&(vals[0]),c*sizeof(mreal));
102 i += c;
103 }
104 setlocale(LC_NUMERIC, loc.c_str());
105 }
106 //-----------------------------------------------------------------------------
mgl_data_set(HMDT d,HCDT a)107 void MGL_EXPORT mgl_data_set(HMDT d, HCDT a)
108 {
109 if(!a) return;
110 // d->temp = a->temp; d->s = a->s; d->func = a->func; d->o = a->o;
111
112 mgl_data_create(d, a->GetNx(), a->GetNy(), a->GetNz());
113 const mglData *dd = dynamic_cast<const mglData *>(a); // faster for mglData
114 if(dd) // this one should be much faster
115 memcpy(d->a, dd->a, d->nx*d->ny*d->nz*sizeof(mreal));
116 else // very inefficient!!!
117 #pragma omp parallel for collapse(3)
118 for(long k=0;k<d->nz;k++) for(long j=0;j<d->ny;j++) for(long i=0;i<d->nx;i++)
119 d->a[i+d->nx*(j+d->ny*k)] = a->v(i,j,k);
120 }
mgl_data_set_(uintptr_t * d,uintptr_t * a)121 void MGL_EXPORT mgl_data_set_(uintptr_t *d, uintptr_t *a) { mgl_data_set(_DT_,_DA_(a)); }
122 //-----------------------------------------------------------------------------
mgl_data_set_values(HMDT d,const char * v,long NX,long NY,long NZ)123 void MGL_EXPORT mgl_data_set_values(HMDT d, const char *v,long NX,long NY,long NZ)
124 {
125 if(NX<1 || NY <1 || NZ<1) return;
126 long n=strlen(v)+1;
127 char *buf = new char[n];
128 memcpy(buf,v,n);
129 mglFromStr(d,buf,NX,NY,NZ);
130 delete []buf;
131 }
mgl_data_set_values_(uintptr_t * d,const char * val,int * nx,int * ny,int * nz,int l)132 void MGL_EXPORT mgl_data_set_values_(uintptr_t *d, const char *val, int *nx, int *ny, int *nz, int l)
133 { char *s=new char[l+1]; memcpy(s,val,l); s[l]=0;
134 mgl_data_set_values(_DT_,s,*nx,*ny,*nz); delete []s; }
135 //-----------------------------------------------------------------------------
mgl_data_set_vector(HMDT d,gsl_vector * v)136 void MGL_EXPORT mgl_data_set_vector(HMDT d, gsl_vector *v)
137 {
138 #if MGL_HAVE_GSL
139 if(!v || v->size<1) return;
140 mgl_data_create(d, v->size,1,1);
141 #pragma omp parallel for
142 for(long i=0;i<d->nx;i++) d->a[i] = v->data[i*v->stride];
143 #endif
144 }
145 //-----------------------------------------------------------------------------
mgl_data_set_matrix(HMDT d,gsl_matrix * m)146 void MGL_EXPORT mgl_data_set_matrix(HMDT d, gsl_matrix *m)
147 {
148 #if MGL_HAVE_GSL
149 if(!m || m->size1<1 || m->size2<1) return;
150 mgl_data_create(d, m->size1,m->size2,1);
151 #pragma omp parallel for collapse(2)
152 for(long j=0;j<d->ny;j++) for(long i=0;i<d->nx;i++)
153 d->a[i+j*d->nx] = m->data[i * m->tda + j];
154 #endif
155 }
156 //-----------------------------------------------------------------------------
mgl_data_set_float(HMDT d,const float * A,long NX,long NY,long NZ)157 void MGL_EXPORT mgl_data_set_float(HMDT d, const float *A,long NX,long NY,long NZ)
158 {
159 if(NX<=0 || NY<=0 || NZ<=0) return;
160 mgl_data_create(d, NX,NY,NZ); if(!A) return;
161 #if MGL_USE_DOUBLE
162 #pragma omp parallel for
163 for(long i=0;i<NX*NY*NZ;i++) d->a[i] = A[i];
164 #else
165 memcpy(d->a,A,NX*NY*NZ*sizeof(float));
166 #endif
167 }
168 //-----------------------------------------------------------------------------
mgl_data_set_double(HMDT d,const double * A,long NX,long NY,long NZ)169 void MGL_EXPORT mgl_data_set_double(HMDT d, const double *A,long NX,long NY,long NZ)
170 {
171 if(NX<=0 || NY<=0 || NZ<=0) return;
172 mgl_data_create(d, NX,NY,NZ); if(!A) return;
173 #if MGL_USE_DOUBLE
174 memcpy(d->a,A,NX*NY*NZ*sizeof(double));
175 #else
176 #pragma omp parallel for
177 for(long i=0;i<NX*NY*NZ;i++) d->a[i] = A[i];
178 #endif
179 }
180 //-----------------------------------------------------------------------------
mgl_data_set_float2(HMDT d,float const * const * A,long N1,long N2)181 void MGL_EXPORT mgl_data_set_float2(HMDT d, float const * const *A,long N1,long N2)
182 {
183 if(N1<=0 || N2<=0) return;
184 mgl_data_create(d, N2,N1,1); if(!A) return;
185 #if MGL_USE_DOUBLE
186 #pragma omp parallel for collapse(2)
187 for(long i=0;i<N1;i++) for(long j=0;j<N2;j++) d->a[j+i*N2] = A[i][j];
188 #else
189 #pragma omp parallel for
190 for(long i=0;i<N1;i++) memcpy(d->a+i*N2,A[i],N2*sizeof(float));
191 #endif
192 }
193 //-----------------------------------------------------------------------------
mgl_data_set_double2(HMDT d,double const * const * A,long N1,long N2)194 void MGL_EXPORT mgl_data_set_double2(HMDT d, double const *const *A,long N1,long N2)
195 {
196 if(N1<=0 || N2<=0) return;
197 mgl_data_create(d, N2,N1,1); if(!A) return;
198 #if MGL_USE_DOUBLE
199 #pragma omp parallel for
200 for(long i=0;i<N1;i++) memcpy(d->a+i*N2,A[i],N2*sizeof(double));
201 #else
202 #pragma omp parallel for collapse(2)
203 for(long i=0;i<N1;i++) for(long j=0;j<N2;j++) d->a[j+i*N2] = A[i][j];
204 #endif
205 }
206 //-----------------------------------------------------------------------------
mgl_data_set_float3(HMDT d,float const * const * const * A,long N1,long N2,long N3)207 void MGL_EXPORT mgl_data_set_float3(HMDT d, float const * const * const *A,long N1,long N2,long N3)
208 {
209 if(N1<=0 || N2<=0 || N3<=0) return;
210 mgl_data_create(d, N3,N2,N1); if(!A) return;
211 #if MGL_USE_DOUBLE
212 #pragma omp parallel for collapse(3)
213 for(long i=0;i<N1;i++) for(long j=0;j<N2;j++) for(long k=0;k<N3;k++)
214 d->a[k+N3*(j+i*N2)] = A[i][j][k];
215 #else
216 #pragma omp parallel for collapse(2)
217 for(long i=0;i<N1;i++) for(long j=0;j<N2;j++)
218 memcpy(d->a+N3*(j+i*N2),A[i][j],N3*sizeof(float));
219 #endif
220 }
221 //-----------------------------------------------------------------------------
mgl_data_set_double3(HMDT d,double const * const * const * A,long N1,long N2,long N3)222 void MGL_EXPORT mgl_data_set_double3(HMDT d, double const * const * const *A,long N1,long N2,long N3)
223 {
224 if(N1<=0 || N2<=0 || N3<=0) return;
225 mgl_data_create(d, N3,N2,N1); if(!A) return;
226 #if MGL_USE_DOUBLE
227 #pragma omp parallel for collapse(2)
228 for(long i=0;i<N1;i++) for(long j=0;j<N2;j++)
229 memcpy(d->a+N3*(j+i*N2),A[i][j],N3*sizeof(double));
230 #else
231 #pragma omp parallel for collapse(3)
232 for(long i=0;i<N1;i++) for(long j=0;j<N2;j++) for(long k=0;k<N3;k++)
233 d->a[k+N3*(j+i*N2)] = A[i][j][k];
234 #endif
235 }
236 //-----------------------------------------------------------------------------
mgl_data_set_float1_(uintptr_t * d,const float * A,int * NX)237 void MGL_EXPORT mgl_data_set_float1_(uintptr_t *d, const float *A,int *NX)
238 { mgl_data_set_float(_DT_,A,*NX,1,1); }
mgl_data_set_double1_(uintptr_t * d,const double * A,int * NX)239 void MGL_EXPORT mgl_data_set_double1_(uintptr_t *d, const double *A,int *NX)
240 { mgl_data_set_double(_DT_,A,*NX,1,1); }
mgl_data_set_float_(uintptr_t * d,const float * A,int * NX,int * NY,int * NZ)241 void MGL_EXPORT mgl_data_set_float_(uintptr_t *d, const float *A,int *NX,int *NY,int *NZ)
242 { mgl_data_set_float(_DT_,A,*NX,*NY,*NZ); }
mgl_data_set_double_(uintptr_t * d,const double * A,int * NX,int * NY,int * NZ)243 void MGL_EXPORT mgl_data_set_double_(uintptr_t *d, const double *A,int *NX,int *NY,int *NZ)
244 { mgl_data_set_double(_DT_,A,*NX,*NY,*NZ); }
mgl_data_set_float2_(uintptr_t * d,const float * A,int * N1,int * N2)245 void MGL_EXPORT mgl_data_set_float2_(uintptr_t *d, const float *A,int *N1,int *N2)
246 { mgl_data_set_float(_DT_,A,*N1,*N2,1); }
mgl_data_set_double2_(uintptr_t * d,const double * A,int * N1,int * N2)247 void MGL_EXPORT mgl_data_set_double2_(uintptr_t *d, const double *A,int *N1,int *N2)
248 { mgl_data_set_double(_DT_,A,*N1,*N2,1); }
mgl_data_set_float3_(uintptr_t * d,const float * A,int * N1,int * N2,int * N3)249 void MGL_EXPORT mgl_data_set_float3_(uintptr_t *d, const float *A,int *N1,int *N2,int *N3)
250 { mgl_data_set_float(_DT_,A,*N1,*N2,*N3); }
mgl_data_set_double3_(uintptr_t * d,const double * A,int * N1,int * N2,int * N3)251 void MGL_EXPORT mgl_data_set_double3_(uintptr_t *d, const double *A,int *N1,int *N2,int *N3)
252 { mgl_data_set_double(_DT_,A,*N1,*N2,*N3); }
253 //-----------------------------------------------------------------------------
mgl_data_rearrange(HMDT d,long mx,long my,long mz)254 void MGL_EXPORT mgl_data_rearrange(HMDT d, long mx,long my,long mz)
255 {
256 if(mx<1) return; // wrong mx
257 if(my<1) { my = d->nx*d->ny*d->nz/mx; mz = 1; }
258 else if(mz<1) mz = (d->nx*d->ny*d->nz)/(mx*my);
259 long m = mx*my*mz;
260 if(m==0 || m>d->nx*d->ny*d->nz) return; // too high desired dimensions
261 d->nx = mx; d->ny = my; d->nz = mz; d->NewId();
262 }
mgl_data_rearrange_(uintptr_t * d,int * mx,int * my,int * mz)263 void MGL_EXPORT mgl_data_rearrange_(uintptr_t *d, int *mx, int *my, int *mz)
264 { mgl_data_rearrange(_DT_,*mx,*my,*mz); }
265 //-----------------------------------------------------------------------------
mgl_data_get_id(HCDT d)266 MGL_EXPORT_PURE const char *mgl_data_get_id(HCDT d) { return d->id.s; }
mgl_data_set_id(mglDataA * d,const char * ids)267 void MGL_EXPORT mgl_data_set_id(mglDataA *d, const char *ids) { d->id = ids; }
mgl_data_set_id_(uintptr_t * d,const char * eq,int l)268 void MGL_EXPORT mgl_data_set_id_(uintptr_t *d, const char *eq,int l)
269 { char *s=new char[l+1]; memcpy(s,eq,l); s[l]=0;
270 mgl_data_set_id(_DT_, s); delete []s; }
271 //-----------------------------------------------------------------------------
mgl_data_set_name_w(mglDataA * dat,const wchar_t * name)272 void MGL_EXPORT mgl_data_set_name_w(mglDataA *dat, const wchar_t *name)
273 { dat->s = name; }
mgl_data_get_name_w(HCDT dat)274 MGL_EXPORT_PURE const wchar_t *mgl_data_get_name_w(HCDT dat)
275 { return dat->s.w; }
mgl_data_set_name(mglDataA * dat,const char * name)276 void MGL_EXPORT mgl_data_set_name(mglDataA *dat, const char *name)
277 { MGL_TO_WCS(name,dat->Name(wcs)); }
mgl_data_set_name_(uintptr_t * d,const char * name,int l)278 void MGL_EXPORT mgl_data_set_name_(uintptr_t *d, const char *name,int l)
279 { char *s=new char[l+1]; memcpy(s,name,l); s[l]=0;
280 mgl_data_set_name(_DT_,s); delete []s; }
mgl_data_set_func(mglDataA * dat,void (* func)(void *),void * par)281 void MGL_EXPORT mgl_data_set_func(mglDataA *dat, void (*func)(void *), void *par)
282 { dat->func = func; dat->o = par; }
283 //-----------------------------------------------------------------------------
284 /// Get section separated by symbol ch. This is analog of QString::section().
mgl_str_args(const std::string & str,char ch)285 std::vector<std::string> MGL_EXPORT mgl_str_args(const std::string &str, char ch)
286 {
287 std::vector<size_t> pos; pos.push_back(0);
288 for(size_t p=0; p != std::string::npos;)
289 { p=str.find(ch,p+1); pos.push_back(p?p+1:0); }
290 std::vector<std::string> res;
291 for(size_t i=0;i<pos.size()-1;i++)
292 res.push_back(str.substr(pos[i],pos[i+1]-pos[i]-1));
293 return res;
294 }
295 //-----------------------------------------------------------------------------
296 /// Get section separated by symbol ch. This is analog of QString::section().
mgl_str_arg(const std::string & str,char ch,int n1,int n2)297 std::string MGL_EXPORT mgl_str_arg(const std::string &str, char ch, int n1, int n2)
298 {
299 std::vector<size_t> pos; pos.push_back(0);
300 for(size_t p=0; p != std::string::npos;)
301 { p=str.find(ch,p+1); pos.push_back(p?p+1:0); }
302 std::string res;
303 if(n2<0) n2=n1;
304 if(n1<0 || n1>=long(pos.size())-1 || n2<n1) return res;
305 if(n2>=long(pos.size())) n2=pos.size()-1;
306 res = str.substr(pos[n1],pos[n2+1]-pos[n1]-1);
307 if(res.size()==1 && res[0]==ch) res.clear();
308 return res;
309 }
310 //-----------------------------------------------------------------------------
311 /// Get section separated by symbol ch. This is analog of QString::section().
mgl_wcs_args(const std::wstring & str,wchar_t ch)312 std::vector<std::wstring> MGL_EXPORT mgl_wcs_args(const std::wstring &str, wchar_t ch)
313 {
314 std::vector<size_t> pos; pos.push_back(0);
315 for(size_t p=0; p != std::string::npos;)
316 { p=str.find(ch,p+1); pos.push_back(p?p+1:0); }
317 std::vector<std::wstring> res;
318 for(size_t i=0;i<pos.size()-1;i++)
319 res.push_back(str.substr(pos[i],pos[i+1]-pos[i]-1));
320 return res;
321 }
322 //-----------------------------------------------------------------------------
323 /// Get section separated by symbol ch. This is analog of QString::section().
mgl_wcs_arg(const std::wstring & str,wchar_t ch,int n1,int n2)324 std::wstring MGL_EXPORT mgl_wcs_arg(const std::wstring &str, wchar_t ch, int n1, int n2)
325 {
326 std::vector<size_t> pos; pos.push_back(0);
327 for(size_t p=0; p != std::string::npos;)
328 { p=str.find(ch,p+1); pos.push_back(p?p+1:0); }
329 std::wstring res;
330 if(n2<0) n2=n1;
331 if(n1<0 || n1>=long(pos.size())-1 || n2<n1) return res;
332 if(n2>=long(pos.size())) n2=pos.size()-1;
333 res = str.substr(pos[n1],pos[n2+1]-pos[n1]-1);
334 if(res.size()==1 && res[0]==ch) res.clear();
335 return res;
336 }
337 //-----------------------------------------------------------------------------
338 /// Get string from number.
mgl_str_num(double val)339 std::string MGL_EXPORT mgl_str_num(double val)
340 { char buf[32]; snprintf(buf,32,"%g",val); return std::string(buf); }
mgl_str_num(dual val)341 std::string MGL_EXPORT mgl_str_num(dual val)
342 {
343 char buf[64];
344 double re = real(val), im = imag(val);
345 if(re==0 && im>0) snprintf(buf,64,"i%g",im);
346 else if(re && im<0) snprintf(buf,64,"-i%g",-im);
347 else if(im>0) snprintf(buf,64,"%g+i%g",re,im);
348 else if(im<0) snprintf(buf,64,"%g-i%g",re,-im);
349 else snprintf(buf,64,"%g",re);
350 return std::string(buf);
351 }
352 //-----------------------------------------------------------------------------
mgl_data_to_string(HCDT d,long ns)353 std::string MGL_EXPORT mgl_data_to_string(HCDT d, long ns)
354 {
355 long nx=d->GetNx(), ny=d->GetNy(), nz=d->GetNz();
356 const std::string loc = setlocale(LC_NUMERIC, "C");
357 std::string out;
358 if(ns<0 || (ns>=nz && nz>1)) for(long k=0;k<nz;k++)
359 { // save whole data
360 std::string id = d->GetColumnId();
361 if(!id.empty()) out += "## "+id+'\n';
362 for(long i=0;i<ny;i++)
363 {
364 for(long j=0;j<nx-1;j++) out += mgl_str_num(d->v(j,i,k))+'\t';
365 out += mgl_str_num(d->v(nx-1,i,k))+'\n';
366 }
367 out += "\n";
368 }
369 else
370 { // save selected slice
371 if(nz>1) for(long i=0;i<ny;i++)
372 {
373 for(long j=0;j<nx-1;j++) out += mgl_str_num(d->v(j,i,ns))+'\t';
374 out += mgl_str_num(d->v(nx-1,i,ns))+'\n';
375 }
376 else if(ns<ny) for(long j=0;j<nx;j++) out += mgl_str_num(d->v(j,ns))+'\t';
377 }
378 setlocale(LC_NUMERIC, loc.c_str());
379 return out;
380 }
mgl_data_save(HCDT d,const char * fname,long ns)381 void MGL_EXPORT mgl_data_save(HCDT d, const char *fname,long ns)
382 {
383 FILE *fp = fopen(fname,"w");
384 if(fp) { fprintf(fp,"%s",mgl_data_to_string(d,ns).c_str()); fclose(fp); }
385 }
mgl_data_save_(uintptr_t * d,const char * fname,int * ns,int l)386 void MGL_EXPORT mgl_data_save_(uintptr_t *d, const char *fname,int *ns,int l)
387 { char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0;
388 mgl_data_save(_DT_,s,*ns); delete []s; }
389 //-----------------------------------------------------------------------------
mgl_read_gz(gzFile fp)390 MGL_NO_EXPORT char *mgl_read_gz(gzFile fp)
391 {
392 long size=1024,n=0,m;
393 char *buf=(char*)malloc(size);
394 while((m=gzread(fp,buf+size*n,size))>0)
395 {
396 if(m<size) { buf[size*n+m]=0; break; }
397 n++; buf=(char*)realloc(buf,size*(n+1));
398 memset(buf+size*n,0,size);
399 }
400 return buf;
401 }
402 //-----------------------------------------------------------------------------
mgl_data_read_bin(HMDT dat,const char * fname,int kind)403 int MGL_EXPORT mgl_data_read_bin(HMDT dat, const char *fname, int kind)
404 {
405 FILE *fp = fopen(fname,"rb");
406 if(!fp) return 0;
407 fseek(fp,0,SEEK_END);
408 long len=ftell(fp), n=0; // file length, and number of elements
409 fseek(fp,0,SEEK_SET);
410 switch(kind)
411 {
412 case 0: // double type
413 n = len/sizeof(double);
414 if(n>0)
415 {
416 double *a = new double[n];
417 n = fread(a,sizeof(double),n,fp);
418 dat->Create(n);
419 for(long i=0;i<n;i++) dat->a[i]=a[i];
420 }
421 break;
422 case 1: // float type
423 n = len/sizeof(float);
424 if(n>0)
425 {
426 float *a = new float[n];
427 n = fread(a,sizeof(float),n,fp);
428 dat->Create(n);
429 for(long i=0;i<n;i++) dat->a[i]=a[i];
430 }
431 break;
432 case 2: // long double type
433 n = len/sizeof(long double);
434 if(n>0)
435 {
436 long double *a = new long double[n];
437 n = fread(a,sizeof(long double),n,fp);
438 dat->Create(n);
439 for(long i=0;i<n;i++) dat->a[i]=a[i];
440 }
441 break;
442 case 3: // long int type
443 n = len/sizeof(long);
444 if(n>0)
445 {
446 long *a = new long[n];
447 n = fread(a,sizeof(long),n,fp);
448 dat->Create(n);
449 for(long i=0;i<n;i++) dat->a[i]=a[i];
450 }
451 break;
452 case 4: // int type
453 n = len/sizeof(int);
454 if(n>0)
455 {
456 int *a = new int[n];
457 n = fread(a,sizeof(int),n,fp);
458 dat->Create(n);
459 for(long i=0;i<n;i++) dat->a[i]=a[i];
460 }
461 break;
462 case 5: // short int type
463 n = len/sizeof(short);
464 if(n>0)
465 {
466 short *a = new short[n];
467 n = fread(a,sizeof(short),n,fp);
468 dat->Create(n);
469 for(long i=0;i<n;i++) dat->a[i]=a[i];
470 }
471 break;
472 case 6: // char type
473 n = len/sizeof(char);
474 if(n>0)
475 {
476 char *a = new char[n];
477 n = fread(a,sizeof(char),n,fp);
478 dat->Create(n);
479 for(long i=0;i<n;i++) dat->a[i]=a[i];
480 }
481 break;
482 }
483 return 1;
484 }
mgl_data_read_bin_(uintptr_t * d,const char * fname,int * kind,int l)485 int MGL_EXPORT mgl_data_read_bin_(uintptr_t *d, const char *fname,int *kind,int l)
486 { char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0;
487 int r = mgl_data_read_bin(_DT_, s, *kind); delete []s; return r; }
488 //-----------------------------------------------------------------------------
mgl_data_read(HMDT d,const char * fname)489 int MGL_EXPORT mgl_data_read(HMDT d, const char *fname)
490 {
491 long l=1,m=1,k=1,i;
492 gzFile fp = gzopen(fname,"r");
493 if(!fp)
494 {
495 if(!d->a) mgl_data_create(d, 1,1,1);
496 return 0;
497 }
498 char *buf = mgl_read_gz(fp), *tbuf=buf;
499 while(*buf && *buf<=' ') buf++; // remove leading spaces
500 long nb = strlen(buf); gzclose(fp);
501
502 bool first=false;
503 for(i=nb-1;i>=0;i--) if(buf[i]>' ') break;
504 buf[i+1]=0; nb = i+1; // remove tailing spaces
505 for(i=0;i<nb-1 && !isn(buf[i]);i++) // determine nx
506 {
507 while(buf[i]=='#') { while(!isn(buf[i]) && i<nb) i++; }
508 char ch = buf[i];
509 if(ch>' ' && !first) first=true;
510 if(first && (ch==' ' || ch=='\t' || ch==',' || ch==';') && buf[i+1]>' ') k++;
511 }
512 first = false;
513 for(i=0;i<nb-1;i++) // determine ny
514 {
515 char ch = buf[i];
516 if(ch=='#') while(!isn(buf[i]) && i<nb) i++;
517 if(isn(ch))
518 {
519 while(buf[i+1]==' ' || buf[i+1]=='\t') i++;
520 if(isn(buf[i+1])) {first=true; break; }
521 m++;
522 }
523 if(ch=='\f') break;
524 }
525 if(first) for(i=0;i<nb-1;i++) // determine nz
526 {
527 char ch = buf[i];
528 if(ch=='#') while(!isn(buf[i]) && i<nb) i++;
529 if(isn(ch))
530 {
531 while(buf[i+1]==' ' || buf[i+1]=='\t') i++;
532 if(isn(buf[i+1])) l++;
533 }
534 }
535 else for(i=0;i<nb-1;i++) if(buf[i]=='\f') l++;
536 mglFromStr(d,buf,k,m,l);
537 free(tbuf); return 1;
538 }
mgl_data_read_(uintptr_t * d,const char * fname,int l)539 int MGL_EXPORT mgl_data_read_(uintptr_t *d, const char *fname,int l)
540 { char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0;
541 int r = mgl_data_read(_DT_, s); delete []s; return r; }
542 //-----------------------------------------------------------------------------
mgl_data_scan_file(HMDT d,const char * fname,const char * templ)543 int MGL_EXPORT mgl_data_scan_file(HMDT d,const char *fname, const char *templ)
544 {
545 // first scan for all "%g"
546 char *buf=new char[strlen(templ)+1],*s=buf;
547 strcpy(buf,templ);
548 std::vector<std::string> strs;
549 for(size_t i=0;buf[i];i++)
550 {
551 if(buf[i]=='%' && buf[i+1]=='%') i++;
552 else if(buf[i]=='%' && buf[i+1]=='g')
553 { buf[i]=0; strs.push_back(s); s = buf+i+2; }
554 }
555 delete []buf;
556 if(strs.size()<1) return 0;
557 // read proper lines from file
558 std::vector<const char *> bufs;
559 gzFile fp = gzopen(fname,"r");
560 if(!fp)
561 {
562 if(!d->a) mgl_data_create(d, 1,1,1);
563 return 0;
564 }
565 s = mgl_read_gz(fp); gzclose(fp);
566 size_t len = strs[0].length();
567 const char *s0 = strs[0].c_str();
568 if(!strncmp(s, s0, len)) bufs.push_back(s);
569 for(long i=0;s[i];i++) if(s[i]=='\n')
570 {
571 while(s[i+1]=='\n') i++;
572 s[i]=0; i++;
573 if(!strncmp(s+i, s0, len)) bufs.push_back(s+i);
574 if(!s[i]) break;
575 }
576 // parse lines and collect data
577 size_t nx=strs.size(), ny=bufs.size();
578 if(ny<1)
579 {
580 if(!d->a) mgl_data_create(d, 1,1,1);
581 return 0;
582 }
583 d->Create(nx,ny);
584 for(size_t j=0;j<ny;j++)
585 {
586 const char *c = bufs[j];
587 for(size_t i=0;i<nx;i++)
588 {
589 const char *p = strstr(c,strs[i].c_str());
590 if(!p) break;
591 p += strs[i].length(); c=p;
592 d->a[i+nx*j] = atof(p);
593 }
594 }
595 free(s); return 1;
596 }
mgl_data_scan_file_(uintptr_t * d,const char * fname,const char * templ,int l,int m)597 int MGL_EXPORT mgl_data_scan_file_(uintptr_t *d,const char *fname, const char *templ,int l,int m)
598 { char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0;
599 char *t=new char[m+1]; memcpy(t,templ,m); t[m]=0;
600 int r = mgl_data_scan_file(_DT_, s,t); delete []s; delete []t; return r; }
601 //-----------------------------------------------------------------------------
mgl_data_create(HMDT d,long mx,long my,long mz)602 void MGL_EXPORT mgl_data_create(HMDT d,long mx,long my,long mz)
603 {
604 d->nx = mx>0 ? mx:1; d->ny = my>0 ? my:1; d->nz = mz>0 ? mz:1;
605 if(d->a && !d->link) delete [](d->a);
606 d->a = new mreal[d->nx*d->ny*d->nz];
607 d->NewId(); d->link=false;
608 memset(d->a,0,d->nx*d->ny*d->nz*sizeof(mreal));
609 }
mgl_data_create_(uintptr_t * d,int * nx,int * ny,int * nz)610 void MGL_EXPORT mgl_data_create_(uintptr_t *d, int *nx,int *ny,int *nz)
611 { mgl_data_create(_DT_,*nx,*ny,*nz); }
612 //-----------------------------------------------------------------------------
mgl_data_link(HMDT d,mreal * A,long mx,long my,long mz)613 void MGL_EXPORT mgl_data_link(HMDT d, mreal *A, long mx,long my,long mz)
614 {
615 if(!A) return;
616 if(!d->link && d->a) delete [](d->a);
617 d->nx = mx>0 ? mx:1; d->ny = my>0 ? my:1; d->nz = mz>0 ? mz:1;
618 d->link=true; d->a=A; d->NewId();
619 }
mgl_data_link_(uintptr_t * d,mreal * A,int * nx,int * ny,int * nz)620 void MGL_EXPORT mgl_data_link_(uintptr_t *d, mreal *A, int *nx,int *ny,int *nz)
621 { mgl_data_link(_DT_,A,*nx,*ny,*nz); }
622 //-----------------------------------------------------------------------------
mgl_data_read_dim(HMDT d,const char * fname,long mx,long my,long mz)623 int MGL_EXPORT mgl_data_read_dim(HMDT d, const char *fname,long mx,long my,long mz)
624 {
625 if(mx<=0 || my<=0 || mz<=0) return 0;
626 gzFile fp = gzopen(fname,"r");
627 if(!fp) return 0;
628 char *buf = mgl_read_gz(fp);
629 gzclose(fp);
630 mglFromStr(d,buf,mx,my,mz);
631 free(buf); return 1;
632 }
mgl_data_read_dim_(uintptr_t * d,const char * fname,int * mx,int * my,int * mz,int l)633 int MGL_EXPORT mgl_data_read_dim_(uintptr_t *d, const char *fname,int *mx,int *my,int *mz,int l)
634 { char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0;
635 int r = mgl_data_read_dim(_DT_,s,*mx,*my,*mz); delete []s; return r; }
636 //-----------------------------------------------------------------------------
mgl_data_read_mat(HMDT d,const char * fname,long dim)637 int MGL_EXPORT mgl_data_read_mat(HMDT d, const char *fname, long dim)
638 {
639 if(dim<=0 || dim>3) return 0;
640 gzFile fp = gzopen(fname,"r");
641 if(!fp) return 0;
642 long nx=1, ny=1, nz=1;
643 char *buf = mgl_read_gz(fp);
644 long nb = strlen(buf); gzclose(fp);
645
646 long j=0;
647 if(buf[j]=='#') while(!isn(buf[j])) j++; // skip comment
648 while(j<nb && buf[j]<=' ') j++;
649 if(dim==1)
650 {
651 sscanf(buf+j,"%ld",&nx);
652 while(j<nb && buf[j]!='\n') j++;
653 j++;
654 // while(buf[j]>' ') j++;
655 }
656 else if(dim==2)
657 {
658 sscanf(buf+j,"%ld%ld",&nx,&ny);
659 while(j<nb && buf[j]!='\n') j++;
660 j++;
661 char *b=buf+j;
662 long l=0;
663 for(long i=0;b[i];i++)
664 {
665 while(b[i]=='#') { while(!isn(b[i]) && b[i]) i++; }
666 if(b[i]=='\n') l++;
667 }
668 if(l==nx*ny || l==nx*ny+1) // try to read 3d data (i.e. columns of matrix nx*ny)
669 {
670 nz=ny; ny=nx; nx=1; l=0;
671 bool first = false;
672 for(long i=0;b[i] && !isn(b[i]);i++) // determine nx
673 {
674 while(b[i]=='#') { while(!isn(b[i]) && b[i]) i++; }
675 char ch = b[i];
676 if(ch>' ' && !first) first=true;
677 if(first && (ch==' ' || ch=='\t' || ch==',' || ch==';') && b[i+1]>' ') nx++;
678 }
679 }
680 }
681 else if(dim==3)
682 {
683 sscanf(buf+j,"%ld%ld%ld",&nx,&ny,&nz);
684 while(j<nb && buf[j]!='\n') j++;
685 j++;
686 /* while(buf[j]>' ' && j<nb) j++;
687 while(buf[j]<=' ' && j<nb) j++;
688 while(buf[j]>' ' && j<nb) j++;
689 while(buf[j]<=' ' && j<nb) j++;
690 while(buf[j]>' ' && j<nb) j++;*/
691 }
692 mglFromStr(d,buf+j,nx,ny,nz);
693 free(buf); return 1;
694 }
mgl_data_read_mat_(uintptr_t * d,const char * fname,int * dim,int l)695 int MGL_EXPORT mgl_data_read_mat_(uintptr_t *d, const char *fname,int *dim,int l)
696 { char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0;
697 int r = mgl_data_read_mat(_DT_,s,*dim); delete []s; return r; }
698 //-----------------------------------------------------------------------------
mgl_data_max(HCDT d)699 mreal MGL_EXPORT mgl_data_max(HCDT d)
700 {
701 mreal m1=-INFINITY;
702 long nn=d->GetNN();
703 #pragma omp parallel
704 {
705 mreal m=-INFINITY;
706 #pragma omp for nowait
707 for(long i=0;i<nn;i++)
708 { mreal v = d->vthr(i); m = m<v ? v:m; }
709 #pragma omp critical(max_dat)
710 { m1 = m1>m ? m1:m; }
711 }
712 return m1;
713 }
mgl_data_max_(uintptr_t * d)714 mreal MGL_EXPORT mgl_data_max_(uintptr_t *d) { return mgl_data_max(_DT_); }
715 //-----------------------------------------------------------------------------
mgl_data_min(HCDT d)716 mreal MGL_EXPORT mgl_data_min(HCDT d)
717 {
718 mreal m1=INFINITY;
719 long nn=d->GetNN();
720 #pragma omp parallel
721 {
722 mreal m=INFINITY;
723 #pragma omp for nowait
724 for(long i=0;i<nn;i++)
725 { mreal v = d->vthr(i); m = m>v ? v:m; }
726 #pragma omp critical(min_dat)
727 { m1 = m1<m ? m1:m; }
728 }
729 return m1;
730 }
mgl_data_min_(uintptr_t * d)731 mreal MGL_EXPORT mgl_data_min_(uintptr_t *d) { return mgl_data_min(_DT_); }
732 //-----------------------------------------------------------------------------
mgl_data_neg_max(HCDT d)733 mreal MGL_EXPORT mgl_data_neg_max(HCDT d)
734 {
735 mreal m1=0;
736 long nn=d->GetNN();
737 #pragma omp parallel
738 {
739 mreal m=0;
740 #pragma omp for nowait
741 for(long i=0;i<nn;i++)
742 { mreal v = d->vthr(i); m = m<v && v<0 ? v:m; }
743 #pragma omp critical(nmax_dat)
744 { m1 = m1>m ? m1:m; }
745 }
746 return m1;
747 }
mgl_data_neg_max_(uintptr_t * d)748 mreal MGL_EXPORT mgl_data_neg_max_(uintptr_t *d) { return mgl_data_neg_max(_DT_); }
749 //-----------------------------------------------------------------------------
mgl_data_pos_min(HCDT d)750 mreal MGL_EXPORT mgl_data_pos_min(HCDT d)
751 {
752 mreal m1=INFINITY;
753 long nn=d->GetNN();
754 #pragma omp parallel
755 {
756 mreal m=INFINITY;
757 #pragma omp for nowait
758 for(long i=0;i<nn;i++)
759 { mreal v = d->vthr(i); m = m>v && v>0 ? v:m; }
760 #pragma omp critical(pmin_dat)
761 { m1 = m1<m ? m1:m; }
762 }
763 return m1;
764 }
mgl_data_pos_min_(uintptr_t * d)765 mreal MGL_EXPORT mgl_data_pos_min_(uintptr_t *d) { return mgl_data_pos_min(_DT_); }
766 //-----------------------------------------------------------------------------
mgl_data_max_int(HCDT d,long * i,long * j,long * k)767 mreal MGL_EXPORT mgl_data_max_int(HCDT d, long *i, long *j, long *k)
768 {
769 mreal m1=-INFINITY;
770 long nx=d->GetNx(), ny=d->GetNy(), nn=d->GetNN();
771 #pragma omp parallel
772 {
773 mreal m=-INFINITY;
774 long im=-1,jm=-1,km=-1;
775 #pragma omp for nowait
776 for(long ii=0;ii<nn;ii++)
777 {
778 mreal v = d->vthr(ii);
779 if(m < v)
780 { m=v; im=ii%nx; jm=(ii/nx)%ny; km=ii/(nx*ny); }
781 }
782 #pragma omp critical(max_int)
783 if(m1 < m) { m1=m; *i=im; *j=jm; *k=km; }
784 }
785 return m1;
786 }
mgl_data_max_int_(uintptr_t * d,int * i,int * j,int * k)787 mreal MGL_EXPORT mgl_data_max_int_(uintptr_t *d, int *i, int *j, int *k)
788 { long ii,jj,kk; mreal res=mgl_data_max_int(_DT_,&ii,&jj,&kk);
789 *i=ii; *j=jj; *k=kk; return res; }
790 //-----------------------------------------------------------------------------
mgl_data_min_int(HCDT d,long * i,long * j,long * k)791 mreal MGL_EXPORT mgl_data_min_int(HCDT d, long *i, long *j, long *k)
792 {
793 mreal m1=INFINITY;
794 long nx=d->GetNx(), ny=d->GetNy(), nn=d->GetNN();
795 #pragma omp parallel
796 {
797 mreal m=INFINITY;
798 long im=-1,jm=-1,km=-1;
799 #pragma omp for nowait
800 for(long ii=0;ii<nn;ii++)
801 {
802 mreal v = d->vthr(ii);
803 if(m > v)
804 { m=v; im=ii%nx; jm=(ii/nx)%ny; km=ii/(nx*ny); }
805 }
806 #pragma omp critical(min_int)
807 if(m1 > m) { m1=m; *i=im; *j=jm; *k=km; }
808 }
809 return m1;
810 }
mgl_data_min_int_(uintptr_t * d,int * i,int * j,int * k)811 mreal MGL_EXPORT mgl_data_min_int_(uintptr_t *d, int *i, int *j, int *k)
812 { long ii,jj,kk; mreal res=mgl_data_min_int(_DT_,&ii,&jj,&kk);
813 *i=ii; *j=jj; *k=kk; return res; }
814 //-----------------------------------------------------------------------------
mgl_data_max_first(HCDT d,char dir,long from,long * p1,long * p2)815 long MGL_EXPORT mgl_data_max_first(HCDT d, char dir, long from, long *p1, long *p2)
816 {
817 long n=d->GetNx(), n1=d->GetNy(), n2=d->GetNz(), d1=n, d2=n*n1, dd=1;
818 if(dir=='y') { n=n1; n1=dd=d1; d1=1; }
819 if(dir=='z') { n=n2; n2=n1; n1=d1; d1=1; dd=d2; d2=n2; }
820 bool find=false;
821 if(from>=0)
822 {
823 for(long i=from+1;i<n-1;i++)
824 {
825 #pragma omp parallel for collapse(2)
826 for(long i1=0;i1<n1;i1++) for(long i2=0;i2<n2;i2++)
827 {
828 long ii=i*dd+i1*d1+i2*d2;
829 if(d->vthr(ii)>=d->vthr(ii+dd) && d->vthr(ii)>=d->vthr(ii-dd))
830 { find=true; if(p1) *p1=i1; if(p2) *p2=i2; }
831 }
832 if(find) return i;
833 }
834 }
835 else
836 {
837 for(long i=n+from-1;i>0;i--)
838 {
839 for(long i1=0;i1<n1;i1++) for(long i2=0;i2<n2;i2++)
840 {
841 long ii=i*dd+i1*d1+i2*d2;
842 if(d->vthr(ii)>=d->vthr(ii+dd) && d->vthr(ii)>=d->vthr(ii-dd))
843 { find=true; if(p1) *p1=i1; if(p2) *p2=i2; }
844 }
845 if(find) return i;
846 }
847 }
848 return -1;
849 }
mgl_data_max_first_(uintptr_t * d,const char * dir,long * from,long * p1,long * p2,int)850 long MGL_EXPORT mgl_data_max_first_(uintptr_t *d, const char *dir, long *from, long *p1, long *p2,int)
851 { return mgl_data_max_first(_DT_,*dir,*from,p1,p2); }
852 //-----------------------------------------------------------------------------
mgl_data_max_real(HCDT d,mreal * x,mreal * y,mreal * z)853 mreal MGL_EXPORT mgl_data_max_real(HCDT d, mreal *x, mreal *y, mreal *z)
854 {
855 long im=-1,jm=-1,km=-1;
856 long nx=d->GetNx(), ny=d->GetNy(), nz=d->GetNz();
857 mreal m=mgl_data_max_int(d,&im,&jm,&km), v, v1, v2;
858 *x=im; *y=jm; *z=km;
859
860 v = d->v(im,jm,km);
861 if(nx>2)
862 {
863 if(im==0) im=1;
864 if(im==nx-1)im=nx-2;
865 v1 = d->v(im+1,jm,km); v2 = d->v(im-1,jm,km);
866 *x = (v1+v2-2*v)==0 ? im : im+(v2-v1)/(v1+v2-2*v)/2;
867 }
868 if(ny>2)
869 {
870 if(jm==0) jm=1;
871 if(jm==ny-1)jm=ny-2;
872 v1 = d->v(im,jm+1,km); v2 = d->v(im,jm-1,km);
873 *y = (v1+v2-2*v)==0 ? jm : jm+(v2-v1)/(v1+v2-2*v)/2;
874 }
875 if(nz>2)
876 {
877 if(km==0) km=1;
878 if(km==nz-1)km=nz-2;
879 v1 = d->v(im,jm,km+1); v2 = d->v(im,jm,km-1);
880 *z = (v1+v2-2*v)==0 ? km : km+(v2-v1)/(v1+v2-2*v)/2;
881 }
882 return m;
883 }
mgl_data_max_real_(uintptr_t * d,mreal * x,mreal * y,mreal * z)884 mreal MGL_EXPORT mgl_data_max_real_(uintptr_t *d, mreal *x, mreal *y, mreal *z)
885 { return mgl_data_max_real(_DT_,x,y,z); }
886 //-----------------------------------------------------------------------------
mgl_data_min_real(HCDT d,mreal * x,mreal * y,mreal * z)887 mreal MGL_EXPORT mgl_data_min_real(HCDT d, mreal *x, mreal *y, mreal *z)
888 {
889 long im=-1,jm=-1,km=-1;
890 long nx=d->GetNx(), ny=d->GetNy(), nz=d->GetNz();
891 mreal m=mgl_data_min_int(d,&im,&jm,&km), v, v1, v2;
892 *x=im; *y=jm; *z=km;
893
894 v = d->v(im,jm,km);
895 if(nx>2)
896 {
897 if(im==0) im=1;
898 if(im==nx-1)im=nx-2;
899 v1 = d->v(im+1,jm,km); v2 = d->v(im-1,jm,km);
900 *x = (v1+v2-2*v)==0 ? im : im+(v2-v1)/(v1+v2-2*v)/2;
901 }
902 if(ny>2)
903 {
904 if(jm==0) jm=1;
905 if(jm==ny-1)jm=ny-2;
906 v1 = d->v(im,jm+1,km); v2 = d->v(im,jm-1,km);
907 *y = (v1+v2-2*v)==0 ? jm : jm+(v2-v1)/(v1+v2-2*v)/2;
908 }
909 if(nz>2)
910 {
911 if(km==0) km=1;
912 if(km==nz-1)km=nz-2;
913 v1 = d->v(im,jm,km+1); v2 = d->v(im,jm,km-1);
914 *z = (v1+v2-2*v)==0 ? km : km+(v2-v1)/(v1+v2-2*v)/2;
915 }
916 return m;
917 }
mgl_data_min_real_(uintptr_t * d,mreal * x,mreal * y,mreal * z)918 mreal MGL_EXPORT mgl_data_min_real_(uintptr_t *d, mreal *x, mreal *y, mreal *z)
919 { return mgl_data_min_real(_DT_,x,y,z); }
920 //-----------------------------------------------------------------------------
mgl_data_fill(HMDT d,mreal x1,mreal x2,char dir)921 void MGL_EXPORT mgl_data_fill(HMDT d, mreal x1,mreal x2,char dir)
922 {
923 if(mgl_isnan(x2)) x2=x1;
924 if(dir<'x' || dir>'z') dir='x';
925 long nx=d->nx,ny=d->ny,nz=d->nz;
926 if(dir=='x')
927 {
928 mreal dx = d->nx>1 ? (x2-x1)/(d->nx-1):0;
929 #pragma omp parallel for collapse(2)
930 for(long j=0;j<ny*nz;j++) for(long i=1;i<nx;i++) d->a[i+nx*j] = x1+dx*i;
931 #pragma omp parallel for
932 for(long j=0;j<ny*nz;j++) d->a[nx*j] = x1;
933 }
934 if(dir=='y')
935 {
936 mreal dx = d->ny>1 ? (x2-x1)/(d->ny-1):0;
937 #pragma omp parallel for collapse(3)
938 for(long k=0;k<nz;k++) for(long j=1;j<ny;j++) for(long i=0;i<nx;i++) d->a[i+nx*(j+ny*k)] = x1+dx*j;
939 #pragma omp parallel for collapse(2)
940 for(long j=0;j<nz;j++) for(long i=0;i<nx;i++) d->a[i+nx*ny*j] = x1;
941 }
942 if(dir=='z')
943 {
944 mreal dx = d->nz>1 ? (x2-x1)/(d->nz-1):0;
945 #pragma omp parallel for collapse(2)
946 for(long j=1;j<nz;j++) for(long i=0;i<nx*ny;i++) d->a[i+nx*ny*j] = x1+dx*j;
947 #pragma omp parallel for
948 for(long j=0;j<nx*ny;j++) d->a[j] = x1;
949 }
950 }
mgl_data_fill_(uintptr_t * d,mreal * x1,mreal * x2,const char * dir,int)951 void MGL_EXPORT mgl_data_fill_(uintptr_t *d, mreal *x1,mreal *x2,const char *dir,int)
952 { mgl_data_fill(_DT_,*x1,*x2,*dir); }
953 //-----------------------------------------------------------------------------
mgl_data_norm(HMDT d,mreal v1,mreal v2,int sym,long dim)954 void MGL_EXPORT mgl_data_norm(HMDT d, mreal v1,mreal v2,int sym,long dim)
955 {
956 long s,nn=d->nx*d->ny*d->nz;
957 mreal a1=INFINITY,a2=-INFINITY,v,*a=d->a;
958 s = dim*d->ny*(d->nz>1 ? d->nx : 1);
959 for(long i=s;i<nn;i++) // determines borders of existing data
960 { a1 = a1>a[i] ? a[i]:a1; a2 = a2<a[i] ? a[i]:a2; }
961 if(a1==a2) { if(a1!=0) a1=0.; else a2=1; }
962 if(v1>v2) { v=v1; v1=v2; v2=v; } // swap if uncorrect
963 if(sym) // use symmetric
964 {
965 v2 = -v1>v2 ? -v1:v2; v1 = -v2;
966 a2 = -a1>a2 ? -a1:a2; a1 = -a2;
967 }
968 v2 = (v2-v1)/(a2-a1); v1 = v1-a1*v2;
969 #pragma omp parallel for
970 for(long i=s;i<nn;i++) a[i] = v1 + v2*a[i];
971 }
mgl_data_norm_(uintptr_t * d,mreal * v1,mreal * v2,int * sym,int * dim)972 void MGL_EXPORT mgl_data_norm_(uintptr_t *d, mreal *v1,mreal *v2,int *sym,int *dim)
973 { mgl_data_norm(_DT_,*v1,*v2,*sym,*dim); }
974 //-----------------------------------------------------------------------------
mgl_data_squeeze(HMDT d,long rx,long ry,long rz,long smooth)975 void MGL_EXPORT mgl_data_squeeze(HMDT d, long rx,long ry,long rz,long smooth)
976 {
977 long kx,ky,kz, nx=d->nx, ny=d->ny, nz=d->nz;
978 mreal *b;
979
980 // simple checking
981 if(rx>=nx) rx=nx-1;
982 if(rx<1) rx=1;
983 if(ry>=ny) ry=ny-1;
984 if(ry<1) ry=1;
985 if(rz>=nz) rz=nz-1;
986 if(rz<1) rz=1;
987 // new sizes
988 kx = 1+(nx-1)/rx; ky = 1+(ny-1)/ry; kz = 1+(nz-1)/rz;
989 b = new mreal[kx*ky*kz];
990 if(!smooth)
991 #pragma omp parallel for collapse(3)
992 for(long k=0;k<kz;k++) for(long j=0;j<ky;j++) for(long i=0;i<kx;i++)
993 b[i+kx*(j+ky*k)] = d->a[i*rx+nx*(j*ry+ny*rz*k)];
994 else
995 #pragma omp parallel for collapse(3)
996 for(long k=0;k<kz;k++) for(long j=0;j<ky;j++) for(long i=0;i<kx;i++)
997 {
998 long dx,dy,dz,i1,j1,k1;
999 dx = (i+1)*rx<=nx ? rx : nx-i*rx;
1000 dy = (j+1)*ry<=ny ? ry : ny-j*ry;
1001 dz = (k+1)*rz<=nz ? rz : nz-k*rz;
1002 mreal s = 0;
1003 for(k1=k*rz;k1<k*rz+dz;k1++) for(j1=j*ry;j1<j*ry+dz;j1++) for(i1=i*rx;i1<i*rx+dx;i1++)
1004 s += d->a[i1+nx*(j1+ny*k1)];
1005 b[i+kx*(j+ky*k)] = s/(dx*dy*dz);
1006 }
1007 if(!d->link) delete [](d->a);
1008 d->a=b; d->nx = kx; d->ny = ky; d->nz = kz; d->NewId(); d->link=false;
1009 }
mgl_data_squeeze_(uintptr_t * d,int * rx,int * ry,int * rz,int * smooth)1010 void MGL_EXPORT mgl_data_squeeze_(uintptr_t *d, int *rx,int *ry,int *rz,int *smooth)
1011 { mgl_data_squeeze(_DT_,*rx,*ry,*rz,*smooth); }
1012 //-----------------------------------------------------------------------------
mgl_data_extend(HMDT d,long n1,long n2)1013 void MGL_EXPORT mgl_data_extend(HMDT d, long n1, long n2)
1014 {
1015 long nx=d->nx, ny=d->ny, nz=d->nz;
1016 if(nz>2 || n1==0) return;
1017 long mx, my, mz;
1018 mreal *b=0;
1019 if(n1>0) // extend to higher dimension(s)
1020 {
1021 n2 = n2>0 ? n2:1;
1022 mx = nx; my = ny>1?ny:n1; mz = ny>1 ? n1 : n2;
1023 b = new mreal[mx*my*mz];
1024 if(ny>1)
1025 #pragma omp parallel for
1026 for(long i=0;i<n1;i++) memcpy(b+i*nx*ny, d->a, nx*ny*sizeof(mreal));
1027 else
1028 #pragma omp parallel for
1029 for(long i=0;i<n1*n2;i++) memcpy(b+i*nx, d->a, nx*sizeof(mreal));
1030 }
1031 else
1032 {
1033 mx = -n1; my = n2<0 ? -n2 : nx; mz = n2<0 ? nx : ny;
1034 if(n2>0 && ny==1) mz = n2;
1035 b = new mreal[mx*my*mz];
1036 if(n2<0)
1037 #pragma omp parallel for collapse(2)
1038 for(long j=0;j<nx;j++) for(long i=0;i<mx*my;i++)
1039 b[i+mx*my*j] = d->a[j];
1040 else
1041 #pragma omp parallel for collapse(2)
1042 for(long j=0;j<nx*ny;j++) for(long i=0;i<mx;i++)
1043 b[i+mx*j] = d->a[j];
1044 if(n2>0 && ny==1)
1045 #pragma omp parallel for
1046 for(long i=0;i<n2;i++)
1047 memcpy(b+i*mx*my, d->a, mx*my*sizeof(mreal));
1048 }
1049 if(!d->link) delete [](d->a);
1050 d->a=b; d->nx=mx; d->ny=my; d->nz=mz;
1051 d->NewId(); d->link=false;
1052 }
mgl_data_extend_(uintptr_t * d,int * n1,int * n2)1053 void MGL_EXPORT mgl_data_extend_(uintptr_t *d, int *n1, int *n2)
1054 { mgl_data_extend(_DT_,*n1,*n2); }
1055 //-----------------------------------------------------------------------------
mgl_data_transpose(HMDT d,const char * dim)1056 void MGL_EXPORT mgl_data_transpose(HMDT d, const char *dim)
1057 {
1058 long nx=d->nx, ny=d->ny, nz=d->nz, n;
1059 mreal *b=new mreal[nx*ny*nz], *a=d->a;
1060 if(!strcmp(dim,"xzy") || !strcmp(dim,"zy"))
1061 {
1062 #pragma omp parallel for collapse(3)
1063 for(long j=0;j<ny;j++) for(long k=0;k<nz;k++) for(long i=0;i<nx;i++)
1064 b[i+nx*(k+nz*j)] = a[i+nx*(j+ny*k)];
1065 n=nz; nz=ny; ny=n;
1066 }
1067 else if(!strcmp(dim,"yxz") || !strcmp(dim,"yx"))
1068 {
1069 #pragma omp parallel for collapse(3)
1070 for(long k=0;k<nz;k++) for(long i=0;i<nx;i++) for(long j=0;j<ny;j++)
1071 b[j+ny*(i+nx*k)] = a[i+nx*(j+ny*k)];
1072 n=nx; nx=ny; ny=n;
1073 }
1074 else if(!strcmp(dim,"yzx"))
1075 {
1076 #pragma omp parallel for collapse(3)
1077 for(long k=0;k<nz;k++) for(long i=0;i<nx;i++) for(long j=0;j<ny;j++)
1078 b[j+ny*(k+nz*i)] = a[i+nx*(j+ny*k)];
1079 n=nx; nx=ny; ny=nz; nz=n;
1080 }
1081 else if(!strcmp(dim,"zxy"))
1082 {
1083 #pragma omp parallel for collapse(3)
1084 for(long i=0;i<nx;i++) for(long j=0;j<ny;j++) for(long k=0;k<nz;k++)
1085 b[k+nz*(i+nx*j)] = a[i+nx*(j+ny*k)];
1086 n=nx; nx=nz; nz=ny; ny=n;
1087 }
1088 else if(!strcmp(dim,"zyx") || !strcmp(dim,"zx"))
1089 {
1090 #pragma omp parallel for collapse(3)
1091 for(long i=0;i<nx;i++) for(long j=0;j<ny;j++) for(long k=0;k<nz;k++)
1092 b[k+nz*(j+ny*i)] = a[i+nx*(j+ny*k)];
1093 n=nz; nz=nx; nx=n;
1094 }
1095 else memcpy(b,a,nx*ny*nz*sizeof(mreal));
1096 memcpy(a,b,nx*ny*nz*sizeof(mreal)); delete []b;
1097 n=d->nx; d->nx=nx; d->ny=ny; d->nz=nz;
1098 if(nx!=n) d->NewId();
1099 }
mgl_data_transpose_(uintptr_t * d,const char * dim,int l)1100 void MGL_EXPORT mgl_data_transpose_(uintptr_t *d, const char *dim,int l)
1101 { char *s=new char[l+1]; memcpy(s,dim,l); s[l]=0;
1102 mgl_data_transpose(_DT_,s); delete []s; }
1103 //-----------------------------------------------------------------------------
mgl_modify(void * par)1104 static void *mgl_modify(void *par)
1105 {
1106 mglThreadD *t=(mglThreadD *)par;
1107 const mglFormula *f = (const mglFormula *)(t->v);
1108 long nx=t->p[0],ny=t->p[1],nz=t->p[2];
1109 mreal *b=t->a, dx,dy,dz;
1110 const mreal *v=t->b, *w=t->c;
1111 dx=nx>1?1/(nx-1.):0; dy=ny>1?1/(ny-1.):0; dz=nz>1?1/(nz-1.):0;
1112 #if !MGL_HAVE_PTHREAD
1113 #pragma omp parallel for
1114 #endif
1115 for(long i0=t->id;i0<t->n;i0+=mglNumThr)
1116 {
1117 long i=i0%nx, j=((i0/nx)%ny), k=i0/(nx*ny);
1118 b[i0] = f->Calc(i*dx, j*dy, k*dz, b[i0], v?v[i0]:0, w?w[i0]:0);
1119 }
1120 return 0;
1121 }
mgl_data_modify(HMDT d,const char * eq,long dim)1122 void MGL_EXPORT mgl_data_modify(HMDT d, const char *eq,long dim)
1123 {
1124 long nx=d->nx, ny=d->ny, nz=d->nz, par[3]={nx,ny,nz};
1125 if(dim<=0) mgl_data_modify_vw(d,eq,0,0); // fastest variant for whole array
1126 else if(nz>1) // 3D array
1127 {
1128 mglFormula f(eq);
1129 par[2] -= dim; if(par[2]<0) par[2]=0;
1130 mglStartThread(mgl_modify,0,nx*ny*par[2],d->a+nx*ny*dim,0,0,par,&f);
1131 }
1132 else // 2D or 1D array
1133 {
1134 mglFormula f(eq);
1135 par[1] -= dim; if(par[1]<0) par[1]=0;
1136 mglStartThread(mgl_modify,0,nx*par[1],d->a+nx*dim,0,0,par,&f);
1137 }
1138 }
mgl_data_modify_(uintptr_t * d,const char * eq,int * dim,int l)1139 void MGL_EXPORT mgl_data_modify_(uintptr_t *d, const char *eq,int *dim,int l)
1140 { char *s=new char[l+1]; memcpy(s,eq,l); s[l]=0;
1141 mgl_data_modify(_DT_,s,*dim); delete []s; }
1142 //-----------------------------------------------------------------------------
mgl_data_modify_vw(HMDT d,const char * eq,HCDT vdat,HCDT wdat)1143 void MGL_EXPORT mgl_data_modify_vw(HMDT d, const char *eq,HCDT vdat,HCDT wdat)
1144 {
1145 std::wstring s=d->Name(); d->Name(L"u");
1146 mglDataV x(d->nx,d->ny,d->nz, 0,1,'x'); x.Name(L"x");
1147 mglDataV y(d->nx,d->ny,d->nz, 0,1,'y'); y.Name(L"y");
1148 mglDataV z(d->nx,d->ny,d->nz, 0,1,'z'); z.Name(L"z");
1149 mglDataV i(d->nx,d->ny,d->nz, 0,d->nx-1,'x'); i.Name(L"i");
1150 mglDataV j(d->nx,d->ny,d->nz, 0,d->ny-1,'y'); j.Name(L"j");
1151 mglDataV k(d->nx,d->ny,d->nz, 0,d->nz-1,'z'); k.Name(L"k");
1152 mglDataV r(d->nx,d->ny,d->nz); r.Name(L"#$mgl");
1153 mglData v(vdat), w(wdat); v.Name(L"v"); w.Name(L"w");
1154 std::vector<mglDataA*> list;
1155 list.push_back(&x); list.push_back(&y); list.push_back(&z); list.push_back(d);
1156 list.push_back(&v); list.push_back(&w); list.push_back(&r);
1157 list.push_back(&i); list.push_back(&j); list.push_back(&k);
1158 d->Move(mglFormulaCalc(eq,list)); d->Name(s.c_str());
1159 }
mgl_data_modify_vw_(uintptr_t * d,const char * eq,uintptr_t * v,uintptr_t * w,int l)1160 void MGL_EXPORT mgl_data_modify_vw_(uintptr_t *d, const char *eq, uintptr_t *v, uintptr_t *w,int l)
1161 { char *s=new char[l+1]; memcpy(s,eq,l); s[l]=0;
1162 mgl_data_modify_vw(_DT_,s,_DA_(v),_DA_(w)); delete []s; }
1163 //-----------------------------------------------------------------------------
1164 #if MGL_HAVE_HDF4
mgl_data_read_hdf4(HMDT d,const char * fname,const char * data)1165 int MGL_EXPORT mgl_data_read_hdf4(HMDT d,const char *fname,const char *data)
1166 {
1167 int32 sd = SDstart(fname,DFACC_READ), nn, i;
1168 if(sd==-1) return 0; // is not a HDF4 file
1169 char name[64];
1170 SDfileinfo(sd,&nn,&i);
1171 for(i=0;i<nn;i++)
1172 {
1173 int32 sds, rank, dims[32], type, attr, in[2]={0,0};
1174 sds = SDselect(sd,i);
1175 SDgetinfo(sds,name,&rank,dims,&type,&attr);
1176 if(!strcmp(name,data)) // as I understand there are possible many datas with the same name
1177 {
1178 if(rank==1) { dims[2]=dims[0]; dims[0]=dims[1]=1; }
1179 else if(rank==2) { dims[2]=dims[1]; dims[1]=dims[0]; dims[0]=1; }
1180 // else if(rank>3) continue;
1181 long mm=dims[0]*dims[1]*dims[2];
1182 if(type==DFNT_FLOAT32)
1183 {
1184 float *b = new float[mm];
1185 SDreaddata(sds,in,0,dims,b);
1186 mgl_data_set_float(d,b,dims[2],dims[1],dims[0]);
1187 delete []b;
1188 }
1189 if(type==DFNT_FLOAT64)
1190 {
1191 double *b = new double[mm];
1192 SDreaddata(sds,in,0,dims,b);
1193 mgl_data_set_double(d,b,dims[2],dims[1],dims[0]);
1194 delete []b;
1195 }
1196 }
1197 SDendaccess(sds);
1198 }
1199 SDend(sd);
1200 return 1;
1201 }
1202 #else
mgl_data_read_hdf4(HMDT,const char *,const char *)1203 int MGL_EXPORT mgl_data_read_hdf4(HMDT ,const char *,const char *)
1204 { mgl_set_global_warn(_("HDF4 support was disabled. Please, enable it and rebuild MathGL.")); return 0; }
1205 #endif
1206 //-----------------------------------------------------------------------------
1207 #if MGL_HAVE_HDF5
mgl_dual_save_hdf(mdual val,const char * fname,const char * data,int rewrite)1208 void MGL_EXPORT mgl_dual_save_hdf(mdual val,const char *fname,const char *data,int rewrite)
1209 {
1210 hid_t hf,hd,hs;
1211 hsize_t dims[4]={1,2};
1212 long rank = 2, res;
1213 H5Eset_auto(0,0);
1214 res=H5Fis_hdf5(fname);
1215 if(res>0 && !rewrite) hf = H5Fopen(fname, H5F_ACC_RDWR, H5P_DEFAULT);
1216 else hf = H5Fcreate(fname, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
1217 if(hf<0) return;
1218 hs = H5Screate_simple(rank, dims, 0);
1219 #if MGL_USE_DOUBLE
1220 hid_t mem_type_id = H5T_NATIVE_DOUBLE;
1221 #else
1222 hid_t mem_type_id = H5T_NATIVE_FLOAT;
1223 #endif
1224 hd = H5Dcreate(hf, data, mem_type_id, hs, H5P_DEFAULT);
1225 H5Dwrite(hd, mem_type_id, hs, hs, H5P_DEFAULT, &val);
1226 H5Dclose(hd); H5Sclose(hs); H5Fclose(hf);
1227 }
1228 //-----------------------------------------------------------------------------
mgl_real_save_hdf(double val,const char * fname,const char * data,int rewrite)1229 void MGL_EXPORT mgl_real_save_hdf(double val,const char *fname,const char *data,int rewrite)
1230 {
1231 hid_t hf,hd,hs;
1232 hsize_t dims[3]={1,1,1};
1233 long rank = 1, res;
1234 H5Eset_auto(0,0);
1235 res=H5Fis_hdf5(fname);
1236 if(res>0 && !rewrite) hf = H5Fopen(fname, H5F_ACC_RDWR, H5P_DEFAULT);
1237 else hf = H5Fcreate(fname, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
1238 if(hf<0) return;
1239 hs = H5Screate_simple(rank, dims, 0);
1240 hid_t mem_type_id = H5T_NATIVE_DOUBLE;
1241 hd = H5Dcreate(hf, data, mem_type_id, hs, H5P_DEFAULT);
1242 H5Dwrite(hd, mem_type_id, hs, hs, H5P_DEFAULT, &val);
1243 H5Dclose(hd); H5Sclose(hs); H5Fclose(hf);
1244 }
1245 //-----------------------------------------------------------------------------
mgl_int_save_hdf(long val,const char * fname,const char * data,int rewrite)1246 void MGL_EXPORT mgl_int_save_hdf(long val,const char *fname,const char *data,int rewrite)
1247 {
1248 hid_t hf,hd,hs;
1249 hsize_t dims[3]={1,1,1};
1250 long rank = 1, res;
1251 H5Eset_auto(0,0);
1252 res=H5Fis_hdf5(fname);
1253 if(res>0 && !rewrite) hf = H5Fopen(fname, H5F_ACC_RDWR, H5P_DEFAULT);
1254 else hf = H5Fcreate(fname, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
1255 if(hf<0) return;
1256 hs = H5Screate_simple(rank, dims, 0);
1257 hid_t mem_type_id = H5T_NATIVE_LONG;
1258 hd = H5Dcreate(hf, data, mem_type_id, hs, H5P_DEFAULT);
1259 H5Dwrite(hd, mem_type_id, hs, hs, H5P_DEFAULT, &val);
1260 H5Dclose(hd); H5Sclose(hs); H5Fclose(hf);
1261 }
1262 //-----------------------------------------------------------------------------
mgl_data_save_hdf(HCDT dat,const char * fname,const char * data,int rewrite)1263 void MGL_EXPORT mgl_data_save_hdf(HCDT dat,const char *fname,const char *data,int rewrite)
1264 {
1265 const mglData *d = dynamic_cast<const mglData *>(dat); // NOTE: slow for non-mglData
1266 if(!d) { mglData d(dat); mgl_data_save_hdf(&d,fname,data,rewrite); return; }
1267 hid_t hf,hd,hs;
1268 hsize_t dims[3];
1269 long rank = 3, res;
1270 H5Eset_auto(0,0);
1271 res=H5Fis_hdf5(fname);
1272 if(res>0 && !rewrite) hf = H5Fopen(fname, H5F_ACC_RDWR, H5P_DEFAULT);
1273 else hf = H5Fcreate(fname, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
1274 if(hf<0) return;
1275 if(d->nz==1 && d->ny == 1) { rank=1; dims[0]=d->nx; }
1276 else if(d->nz==1) { rank=2; dims[0]=d->ny; dims[1]=d->nx; }
1277 else { rank=3; dims[0]=d->nz; dims[1]=d->ny; dims[2]=d->nx; }
1278 hs = H5Screate_simple(rank, dims, 0);
1279 #if MGL_USE_DOUBLE
1280 hid_t mem_type_id = H5T_NATIVE_DOUBLE;
1281 #else
1282 hid_t mem_type_id = H5T_NATIVE_FLOAT;
1283 #endif
1284 hd = H5Dcreate(hf, data, mem_type_id, hs, H5P_DEFAULT);
1285 H5Dwrite(hd, mem_type_id, hs, hs, H5P_DEFAULT, d->a);
1286 H5Dclose(hd); H5Sclose(hs); H5Fclose(hf);
1287 }
1288 //-----------------------------------------------------------------------------
mgl_data_read_hdf(HMDT d,const char * fname,const char * data)1289 int MGL_EXPORT mgl_data_read_hdf(HMDT d,const char *fname,const char *data)
1290 {
1291 hid_t hf,hd,hs;
1292 long rank, res = H5Fis_hdf5(fname);
1293 if(res<=0) return mgl_data_read_hdf4(d,fname,data);
1294 hf = H5Fopen(fname, H5F_ACC_RDONLY, H5P_DEFAULT);
1295 if(hf<0) return 0;
1296 hd = H5Dopen(hf,data);
1297 if(hd<0) { H5Fclose(hf); return 0; }
1298 hs = H5Dget_space(hd);
1299 if(hs<0) { H5Dclose(hd); H5Fclose(hf); return 0; }
1300 rank = H5Sget_simple_extent_ndims(hs);
1301 if(rank>0 && rank<=3)
1302 {
1303 hsize_t dims[3];
1304 H5Sget_simple_extent_dims(hs,dims,0);
1305 if(rank==1) { dims[2]=dims[0]; dims[0]=dims[1]=1; }
1306 else if(rank==2) { dims[2]=dims[1]; dims[1]=dims[0]; dims[0]=1; }
1307 // else if(rank>3) continue;
1308 mgl_data_create(d,dims[2],dims[1],dims[0]);
1309 #if MGL_USE_DOUBLE
1310 H5Dread(hd, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, d->a);
1311 #else
1312 H5Dread(hd, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, H5P_DEFAULT, d->a);
1313 #endif
1314 }
1315 H5Sclose(hs); H5Dclose(hd); H5Fclose(hf); return 1;
1316 }
1317 //-----------------------------------------------------------------------------
mgl_datas_hdf_str(const char * fname)1318 MGL_EXPORT const char * const * mgl_datas_hdf_str(const char *fname)
1319 {
1320 static std::vector<std::string> names;
1321 static const char **res=0;
1322 hid_t hf,hg,hd,ht;
1323 hf = H5Fopen(fname, H5F_ACC_RDONLY, H5P_DEFAULT); names.clear();
1324 if(!hf) return 0;
1325 hg = H5Gopen(hf,"/");
1326 hsize_t num;
1327 char name[256];
1328 H5Gget_num_objs(hg, &num); // replace by H5G_info_t t; H5Gget_info(hg,&t); num=t.nlinks;
1329 for(hsize_t i=0;i<num;i++)
1330 {
1331 if(H5Gget_objtype_by_idx(hg, i)!=H5G_DATASET) continue;
1332 H5Gget_objname_by_idx(hg, i, name, 256); // replace by H5Lget_name_by_idx(hg,".",i,0,0,name,256,0) ?!
1333 hd = H5Dopen(hf,name);
1334 ht = H5Dget_type(hd);
1335 if(H5Tget_class(ht)==H5T_FLOAT || H5Tget_class(ht)==H5T_INTEGER) names.push_back(name);
1336 H5Dclose(hd); H5Tclose(ht);
1337 }
1338 H5Gclose(hg); H5Fclose(hf); names.push_back("");
1339 if(res) delete []res;
1340 size_t nn = names.size();
1341 res = new const char*[nn+1];
1342 for(size_t i=0;i<nn;i++) res[i]=names[i].c_str();
1343 res[nn]=NULL; return res;
1344 }
1345
mgl_datas_hdf(const char * fname,char * buf,long size)1346 long MGL_EXPORT mgl_datas_hdf(const char *fname, char *buf, long size)
1347 {
1348 const char * const *res = mgl_datas_hdf_str(fname);
1349 if(!res) return 0;
1350 long n=0, len=1;
1351 while(res[n][0]) { len += strlen(res[n])+1; n++; }
1352 if(len>size) return -long(len);
1353 strcpy(buf,res[0]);
1354 for(long i=1;i<n;i++) { strcat(buf,"\t"); strcat(buf,res[i]); }
1355 return n;
1356 }
1357 #else
mgl_data_save_hdf(HCDT,const char *,const char *,int)1358 void MGL_EXPORT mgl_data_save_hdf(HCDT ,const char *,const char *,int )
1359 { mgl_set_global_warn(_("HDF5 support was disabled. Please, enable it and rebuild MathGL.")); }
mgl_datas_hdf_str(const char * fname)1360 MGL_EXPORT const char * const * mgl_datas_hdf_str(const char *fname)
1361 { mgl_set_global_warn(_("HDF5 support was disabled. Please, enable it and rebuild MathGL.")); return 0;}
mgl_datas_hdf(const char *,char *,long)1362 long MGL_EXPORT mgl_datas_hdf(const char *, char *, long )
1363 { mgl_set_global_warn(_("HDF5 support was disabled. Please, enable it and rebuild MathGL.")); return 0;}
mgl_data_read_hdf(HMDT,const char *,const char *)1364 int MGL_EXPORT mgl_data_read_hdf(HMDT ,const char *,const char *)
1365 { mgl_set_global_warn(_("HDF5 support was disabled. Please, enable it and rebuild MathGL.")); return 0;}
mgl_dual_save_hdf(mdual val,const char * fname,const char * data,int rewrite)1366 void MGL_EXPORT mgl_dual_save_hdf(mdual val,const char *fname,const char *data,int rewrite)
1367 { mgl_set_global_warn(_("HDF5 support was disabled. Please, enable it and rebuild MathGL.")); }
mgl_real_save_hdf(double val,const char * fname,const char * data,int rewrite)1368 void MGL_EXPORT mgl_real_save_hdf(double val,const char *fname,const char *data,int rewrite)
1369 { mgl_set_global_warn(_("HDF5 support was disabled. Please, enable it and rebuild MathGL.")); }
mgl_int_save_hdf(long val,const char * fname,const char * data,int rewrite)1370 void MGL_EXPORT mgl_int_save_hdf(long val,const char *fname,const char *data,int rewrite)
1371 { mgl_set_global_warn(_("HDF5 support was disabled. Please, enable it and rebuild MathGL.")); }
1372 #endif
1373 //-----------------------------------------------------------------------------
mgl_data_read_hdf_(uintptr_t * d,const char * fname,const char * data,int l,int n)1374 int MGL_EXPORT mgl_data_read_hdf_(uintptr_t *d, const char *fname, const char *data,int l,int n)
1375 { char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0;
1376 char *t=new char[n+1]; memcpy(t,data,n); t[n]=0;
1377 int r = mgl_data_read_hdf(_DT_,s,t); delete []s; delete []t; return r; }
mgl_data_save_hdf_(uintptr_t * d,const char * fname,const char * data,int * rewrite,int l,int n)1378 void MGL_EXPORT mgl_data_save_hdf_(uintptr_t *d, const char *fname, const char *data, int *rewrite,int l,int n)
1379 { char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0;
1380 char *t=new char[n+1]; memcpy(t,data,n); t[n]=0;
1381 mgl_data_save_hdf(_DT_,s,t,*rewrite); delete []s; delete []t; }
mgl_datas_hdf_(const char * fname,char * buf,int l,int size)1382 long MGL_EXPORT mgl_datas_hdf_(const char *fname, char *buf, int l, int size)
1383 { char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0;
1384 int r = mgl_datas_hdf(s,buf,size); delete []s; return r; }
mgl_real_save_hdf_(double * val,const char * fname,const char * data,int * rewrite,int l,int n)1385 void MGL_EXPORT mgl_real_save_hdf_(double *val,const char *fname,const char *data,int *rewrite,int l,int n)
1386 { char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0;
1387 char *t=new char[n+1]; memcpy(t,data,n); t[n]=0;
1388 mgl_real_save_hdf(*val,s,t,*rewrite); delete []s; delete []t; }
mgl_int_save_hdf_(long * val,const char * fname,const char * data,int * rewrite,int l,int n)1389 void MGL_EXPORT mgl_int_save_hdf_(long *val,const char *fname,const char *data,int *rewrite,int l,int n)
1390 { char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0;
1391 char *t=new char[n+1]; memcpy(t,data,n); t[n]=0;
1392 mgl_int_save_hdf(*val,s,t,*rewrite); delete []s; delete []t; }
1393 //-----------------------------------------------------------------------------
mgl_add_file(long & kx,long & ky,long & kz,mreal * & b,mglData * d,bool as_slice)1394 bool MGL_EXPORT mgl_add_file(long &kx,long &ky, long &kz, mreal *&b, mglData *d,bool as_slice)
1395 {
1396 if(as_slice && d->nz==1)
1397 {
1398 if(kx==d->nx && d->ny==1)
1399 {
1400 b = (mreal *)realloc(b,kx*(ky+1)*sizeof(mreal));
1401 memcpy(b+kx*ky,d->a,kx*sizeof(mreal)); ky++;
1402 }
1403 else if(kx==d->nx && ky==d->ny)
1404 {
1405 b = (mreal *)realloc(b,kx*ky*(kz+1)*sizeof(mreal));
1406 memcpy(b+kx*ky*kz,d->a,kx*ky*sizeof(mreal)); kz++;
1407 }
1408 else return false;
1409 }
1410 else
1411 {
1412 if(d->ny*d->nz==1 && ky*kz==1)
1413 {
1414 b = (mreal *)realloc(b,(kx+d->nx)*sizeof(mreal));
1415 memcpy(b+kx,d->a,d->nx*sizeof(mreal)); kx+=d->nx;
1416 }
1417 else if(kx==d->nx && kz==1 && d->nz==1)
1418 {
1419 b = (mreal *)realloc(b,kx*(ky+d->ny)*sizeof(mreal));
1420 memcpy(b+kx*ky,d->a,kx*d->ny*sizeof(mreal)); ky+=d->ny;
1421 }
1422 else if(kx==d->nx && ky==d->ny)
1423 {
1424 b = (mreal *)realloc(b,kx*kx*(kz+d->nz)*sizeof(mreal));
1425 memcpy(b+kx*ky*kz,d->a,kx*ky*d->nz*sizeof(mreal)); kz+=d->nz;
1426 }
1427 else return false;
1428 }
1429 return true;
1430 }
1431 //-----------------------------------------------------------------------------
mgl_data_read_range(HMDT dat,const char * templ,double from,double to,double step,int as_slice)1432 int MGL_EXPORT mgl_data_read_range(HMDT dat, const char *templ, double from, double to, double step, int as_slice)
1433 {
1434 mglData d;
1435 mreal t = from, *b;
1436 long kx,ky,kz,n=strlen(templ)+20;
1437 char *fname = new char[n];
1438
1439 //read first file
1440 do{ snprintf(fname,n,templ,t); fname[n-1]=0; t+= step; } while(!mgl_data_read(&d,fname) && t<=to);
1441
1442 if(t>to) { delete []fname; return 0; }
1443 kx = d.nx; ky = d.ny; kz = d.nz;
1444 b = (mreal *)malloc(kx*ky*kz*sizeof(mreal));
1445 memcpy(b,d.a,kx*ky*kz*sizeof(mreal));
1446
1447 // read other files
1448 for(;t<=to;t+=step)
1449 {
1450 snprintf(fname,n,templ,t); fname[n-1]=0;
1451 if(mgl_data_read(&d,fname))
1452 if(!mgl_add_file(kx,ky,kz,b,&d,as_slice))
1453 { delete []fname; free(b); return 0; }
1454 }
1455 dat->Set(b,kx,ky,kz);
1456 delete []fname; free(b);
1457 return 1;
1458 }
mgl_data_read_range_(uintptr_t * d,const char * fname,mreal * from,mreal * to,mreal * step,int * as_slice,int l)1459 int MGL_EXPORT mgl_data_read_range_(uintptr_t *d, const char *fname, mreal *from, mreal *to, mreal *step, int *as_slice,int l)
1460 { char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0;
1461 int r = mgl_data_read_range(_DT_,s,*from,*to,*step,*as_slice); delete []s; return r; }
1462 //-----------------------------------------------------------------------------
mgl_data_read_all(HMDT dat,const char * templ,int as_slice)1463 int MGL_EXPORT mgl_data_read_all(HMDT dat, const char *templ, int as_slice)
1464 {
1465 #ifndef WIN32
1466 mglData d;
1467 glob_t res;
1468 size_t i;
1469 mreal *b;
1470 long kx,ky,kz;
1471 glob (templ, GLOB_TILDE, NULL, &res);
1472
1473 //read first file
1474 for(i=0;i<res.gl_pathc;i++)
1475 if(mgl_data_read(&d,res.gl_pathv[i])) break;
1476
1477 if(i>=res.gl_pathc)
1478 { globfree (&res); return 0; }
1479 kx = d.nx; ky = d.ny; kz = d.nz;
1480 b = (mreal *)malloc(kx*ky*kz*sizeof(mreal));
1481 memcpy(b,d.a,kx*ky*kz*sizeof(mreal));
1482
1483 for(;i<res.gl_pathc;i++)
1484 {
1485 if(mgl_data_read(&d,res.gl_pathv[i]))
1486 if(!mgl_add_file(kx,ky,kz,b,&d,as_slice))
1487 { globfree (&res); free(b); return 0; }
1488 }
1489 dat->Set(b,kx,ky,kz);
1490
1491 globfree (&res); free(b);
1492 return 1;
1493 #else
1494 return 0;
1495 #endif
1496 }
mgl_data_read_all_(uintptr_t * d,const char * fname,int * as_slice,int l)1497 int MGL_EXPORT mgl_data_read_all_(uintptr_t *d, const char *fname, int *as_slice,int l)
1498 { char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0;
1499 int r = mgl_data_read_all(_DT_,s,*as_slice); delete []s; return r; }
1500 //-----------------------------------------------------------------------------
mgl_data_column(HCDT dat,const char * eq)1501 HMDT MGL_EXPORT mgl_data_column(HCDT dat, const char *eq)
1502 {
1503 std::vector<mglDataA*> list;
1504 const char *id = dat->GetColumnId();
1505 size_t len = strlen(id);
1506 for(size_t i=0;i<len;i++)
1507 {
1508 mglDataT *col = new mglDataT(*dat);
1509 col->SetInd(i,id[i]);
1510 list.push_back(col);
1511 }
1512 if(list.size()==0) return 0; // no named columns
1513 mglDataV *t = new mglDataV(dat->GetNy(),dat->GetNz());
1514 t->Name(L"#$mgl"); list.push_back(t);
1515 HMDT r = mglFormulaCalc(eq,list);
1516 for(size_t i=0;i<list.size();i++) delete list[i];
1517 return r;
1518 }
mgl_data_column_(uintptr_t * d,const char * eq,int l)1519 uintptr_t MGL_EXPORT mgl_data_column_(uintptr_t *d, const char *eq,int l)
1520 { char *s=new char[l+1]; memcpy(s,eq,l); s[l]=0;
1521 uintptr_t r = uintptr_t(mgl_data_column(_DT_,s));
1522 delete []s; return r; }
1523 //-----------------------------------------------------------------------------
mgl_data_limit(HMDT d,mreal v)1524 void MGL_EXPORT mgl_data_limit(HMDT d, mreal v)
1525 {
1526 long n = d->GetNN();
1527 mreal *a = d->a;
1528 #pragma omp parallel for
1529 for(long i=0;i<n;i++)
1530 { mreal b = fabs(a[i]); if(b>v) a[i] *= v/b; }
1531 }
mgl_data_limit_(uintptr_t * d,mreal * v)1532 void MGL_EXPORT mgl_data_limit_(uintptr_t *d, mreal *v)
1533 { mgl_data_limit(_DT_, *v); }
1534 //-----------------------------------------------------------------------------
mgl_data_coil(HMDT d,mreal v1,mreal v2,int sep)1535 void MGL_EXPORT mgl_data_coil(HMDT d, mreal v1, mreal v2, int sep)
1536 {
1537 long n = d->GetNN();
1538 if(mgl_isnan(v2)) v2=-v1;
1539 if(v2<v1) { mreal tmp=v1; v1=v2; v2=tmp; }
1540 mreal *a = d->a, dv = v2-v1;
1541 if(dv==0) return;
1542 long *kk=new long[n];
1543 #pragma omp parallel for
1544 for(long i=0;i<n;i++)
1545 {
1546 kk[i] = mgl_int((a[i]-v1)/dv-0.5);
1547 a[i] -= kk[i]*dv;
1548 }
1549 if(sep)
1550 {
1551 #pragma omp parallel for
1552 for(long i=1;i<n;i++) if(kk[i]!=kk[i-1]) a[i] = NAN;
1553 }
1554 delete []kk;
1555 }
mgl_data_coil_(uintptr_t * d,mreal * v1,mreal * v2,int * sep)1556 void MGL_EXPORT mgl_data_coil_(uintptr_t *d, mreal *v1, mreal *v2, int *sep)
1557 { mgl_data_coil(_DT_, *v1, *v2, *sep); }
1558 //-----------------------------------------------------------------------------
1559 /// Read binary data and swap big-endian to little-endian if swap=true
mgl_fread(FILE * fp,void * vals,size_t size,size_t num,int swap)1560 size_t MGL_EXPORT mgl_fread(FILE *fp, void *vals, size_t size, size_t num, int swap)
1561 {
1562 char *ptr = (char*)vals;
1563 size_t r = fread(ptr,size,num,fp);
1564 if(r && swap)
1565 {
1566 char buf[8], ch;
1567 if(size==4) for(size_t i=0;i<r;i++)
1568 {
1569 memcpy(buf,ptr+i*size,size);
1570 ch=buf[0]; buf[0]=buf[3]; buf[3]=ch;
1571 ch=buf[1]; buf[1]=buf[2]; buf[2]=ch;
1572 }
1573 else if(size==2) for(size_t i=0;i<r;i++)
1574 {
1575 memcpy(buf,ptr+i*size,size);
1576 ch=buf[0]; buf[0]=buf[1]; buf[1]=ch;
1577 }
1578 else if(size==8) for(size_t i=0;i<r;i++)
1579 {
1580 memcpy(buf,ptr+i*size,size);
1581 ch=buf[0]; buf[0]=buf[7]; buf[7]=ch;
1582 ch=buf[1]; buf[1]=buf[6]; buf[6]=ch;
1583 ch=buf[2]; buf[2]=buf[5]; buf[5]=ch;
1584 ch=buf[3]; buf[3]=buf[4]; buf[4]=ch;
1585 }
1586 }
1587 return r;
1588 }
1589 //-----------------------------------------------------------------------------
1590 /// Read data array from Tektronix WFM file
1591 /** Parse Tektronix TDS5000/B, TDS6000/B/C, TDS/CSA7000/B, MSO70000/C, DSA70000/B/C DPO70000/B/C DPO7000/ MSO/DPO5000. */
mgl_data_read_wfm(HMDT d,const char * fname,long num,long step,long start)1592 int MGL_EXPORT mgl_data_read_wfm(HMDT d,const char *fname, long num, long step/*=1*/, long start/*=0*/)
1593 {
1594 /* if(step<1) step=1;
1595 if(start<0) start=0;
1596 FILE *fp = fopen(fname,"rb");
1597 if(!fp) return 0; // couldn't open file
1598 unsigned short byte_order;
1599 fread(&byte_order,2,1,fp);
1600 bool byteorder; // TODO
1601 */ return 0;
1602 }
mgl_data_read_wfm_(uintptr_t * d,const char * fname,long * num,long * step,long * start,int l)1603 int MGL_EXPORT mgl_data_read_wfm_(uintptr_t *d, const char *fname, long *num, long *step, long *start,int l)
1604 { char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0;
1605 int r = mgl_data_read_wfm(_DT_,s,*num,*step,*start);
1606 delete []s; return r; }
1607 /// Read data array from Matlab MAT file (parse versions 4 and 5)
mgl_data_read_matlab(HMDT d,const char * fname,const char * data)1608 int MGL_EXPORT mgl_data_read_matlab(HMDT d,const char *fname,const char *data)
1609 {
1610 // TODO
1611 /**/return 0;
1612 }
mgl_data_read_matlab_(uintptr_t * d,const char * fname,const char * data,int l,int n)1613 int MGL_EXPORT mgl_data_read_matlab_(uintptr_t *d, const char *fname, const char *data,int l,int n)
1614 { char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0;
1615 char *t=new char[n+1]; memcpy(t,data,n); t[n]=0;
1616 int r = mgl_data_read_matlab(_DT_,s,t); delete []s; delete []t; return r; }
1617 //-----------------------------------------------------------------------------
1618