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/datac.h"
27 #include "mgl2/evalc.h"
28 #include "mgl2/thread.h"
29
30 #if MGL_HAVE_HDF5
31 #define H5_USE_16_API
32 #include <hdf5.h>
33 #endif
34
isn(char ch)35 inline bool isn(char ch) {return ch=='\n';}
36 MGL_NO_EXPORT char *mgl_read_gz(gzFile fp);
37 //-----------------------------------------------------------------------------
mgl_create_datac()38 HADT MGL_EXPORT mgl_create_datac() { return new mglDataC; }
mgl_create_datac_size(long nx,long ny,long nz)39 HADT MGL_EXPORT mgl_create_datac_size(long nx, long ny, long nz){ return new mglDataC(nx,ny,nz); }
mgl_create_datac_file(const char * fname)40 HADT MGL_EXPORT mgl_create_datac_file(const char *fname) { return new mglDataC(fname); }
mgl_delete_datac(HADT d)41 void MGL_EXPORT mgl_delete_datac(HADT d) { if(d) delete d; }
42 //-----------------------------------------------------------------------------
mgl_create_datac_()43 uintptr_t MGL_EXPORT mgl_create_datac_()
44 { return uintptr_t(mgl_create_datac()); }
mgl_create_datac_size_(int * nx,int * ny,int * nz)45 uintptr_t MGL_EXPORT mgl_create_datac_size_(int *nx, int *ny, int *nz)
46 { return uintptr_t(mgl_create_datac_size(*nx,*ny,*nz)); }
mgl_create_datac_file_(const char * fname,int l)47 uintptr_t MGL_EXPORT mgl_create_datac_file_(const char *fname,int l)
48 { char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0;
49 uintptr_t r = uintptr_t(mgl_create_datac_file(s)); delete []s; return r; }
mgl_delete_datac_(uintptr_t * d)50 void MGL_EXPORT mgl_delete_datac_(uintptr_t *d)
51 { mgl_delete_datac(_DC_); }
52 //-----------------------------------------------------------------------------
mgl_atoc(const char * s,int adv)53 cmdual MGL_EXPORT mgl_atoc(const char *s, int adv)
54 {
55 double re=0,im=0; size_t ll=strlen(s);
56 while(s[ll]<=' ') ll--;
57 if(adv && *s=='(') sscanf(s,"(%lg,%lg)",&re,&im);
58 else if(*s=='i') { re=0; im=atof(s+1); }
59 else if(adv && *s=='[') sscanf(s,"[%lg,%lg]",&re,&im);
60 else if(adv && *s=='{') sscanf(s,"{%lg,%lg}",&re,&im);
61 else if(s[ll]=='i')
62 {
63 double a,b; //s[ll] = 0;
64 int s1=sscanf(s,"%lg+%lg",&re,&im);
65 int s2=sscanf(s,"%lg-%lg",&a,&b);
66 if(s1<2)
67 {
68 if(s2==2) { re=a; im=-b; }
69 else { im=atof(s); re=0; }
70 }
71 }
72 else
73 {
74 double a,b;
75 int s1=sscanf(s,"%lg+i%lg",&re,&im);
76 int s2=sscanf(s,"%lg-i%lg",&a,&b);
77 if(s1<2)
78 {
79 if(s2==2) { re=a; im=-b; }
80 else { re=atof(s); im=0; }
81 }
82 }
83 return mdual(re,im);
84 }
85 //-----------------------------------------------------------------------------
mglFromStr(HADT d,char * buf,long NX,long NY,long NZ)86 void mglFromStr(HADT d,char *buf,long NX,long NY,long NZ)
87 {
88 if(NX<1 || NY <1 || NZ<1) return;
89 mgl_datac_create(d, NX,NY,NZ);
90 const std::string loc = setlocale(LC_NUMERIC, "C");
91 std::vector<char *> lines;
92 std::vector<std::vector<dual> > numbs;
93 while(*buf && *buf<=' ') buf++;
94 lines.push_back(buf);
95 for(char *s=buf; *s; s++) if(isn(*s))
96 { lines.push_back(s+1); *s = 0; s++; }
97 numbs.resize(lines.size());
98 long nl = long(lines.size());
99 #pragma omp parallel for
100 for(long k=0;k<nl;k++)
101 {
102 char *b = lines[k];
103 long nb = strlen(b);
104 for(long j=0;j<nb;j++)
105 {
106 while(j<nb && b[j]<=' ') j++; // skip first spaces
107 if(j>=nb) break;
108 if(b[j]=='#')
109 {
110 std::string id;
111 if(j<nb-1 && b[j+1]=='#') for(long i=j+2;i<nb;i++)
112 if(b[i]>='a' && b[i]<='z') id.push_back(b[i]);
113 d->SetColumnId(id.c_str());
114 break;
115 }
116 char *s=b+j;
117 long sk=0;
118 while(j<nb && b[j]>' ' && ((b[j]!=',' && b[j]!=' ') || sk!=0) && b[j]!=';')
119 {
120 if(strchr("[{(",b[j])) sk++;
121 if(strchr("]})",b[j])) sk--;
122 j++;
123 }
124 b[j]=0;
125 numbs[k].push_back(mgl_atoc(s,true));
126 }
127 }
128 long i=0, n=NX*NY*NZ;
129 for(long k=0;k<nl && i<n;k++)
130 {
131 std::vector<dual> &vals = numbs[k];
132 long c = vals.size();
133 if(c>n-i) c = n-i;
134 memcpy(d->a+i,&(vals[0]),c*sizeof(dual));
135 i += c;
136 }
137 setlocale(LC_NUMERIC, loc.c_str());
138 }
139 //-----------------------------------------------------------------------------
mgl_datac_set(HADT d,HCDT a)140 void MGL_EXPORT mgl_datac_set(HADT d, HCDT a)
141 {
142 if(!a) return;
143 const mglDataC *dd = dynamic_cast<const mglDataC *>(a); // faster for mglData
144 mgl_datac_create(d, a->GetNx(), a->GetNy(), a->GetNz());
145 if(dd) // this one should be much faster
146 memcpy(d->a, dd->a, d->nx*d->ny*d->nz*sizeof(dual));
147 else // very inefficient!!!
148 {
149 for(long k=0;k<d->nz;k++) for(long j=0;j<d->ny;j++) for(long i=0;i<d->nx;i++)
150 d->a[i+d->nx*(j+d->ny*k)] = a->v(i,j,k);
151 }
152 }
mgl_datac_set_(uintptr_t * d,uintptr_t * a)153 void MGL_EXPORT mgl_datac_set_(uintptr_t *d, uintptr_t *a) { mgl_datac_set(_DC_,_DA_(a)); }
154 //-----------------------------------------------------------------------------
mgl_datac_set_values(HADT d,const char * v,long NX,long NY,long NZ)155 void MGL_EXPORT mgl_datac_set_values(HADT d, const char *v,long NX,long NY,long NZ)
156 {
157 if(NX<1 || NY <1 || NZ<1) return;
158 long n=strlen(v)+1;
159 char *buf = new char[n];
160 memcpy(buf,v,n);
161 mglFromStr(d,buf,NX,NY,NZ);
162 delete []buf;
163 }
mgl_datac_set_values_(uintptr_t * d,const char * val,int * nx,int * ny,int * nz,int l)164 void MGL_EXPORT mgl_datac_set_values_(uintptr_t *d, const char *val, int *nx, int *ny, int *nz, int l)
165 { char *s=new char[l+1]; memcpy(s,val,l); s[l]=0;
166 mgl_datac_set_values(_DC_,s,*nx,*ny,*nz); delete []s; }
167 //-----------------------------------------------------------------------------
mgl_datac_set_vector(HADT d,gsl_vector * v)168 void MGL_EXPORT mgl_datac_set_vector(HADT d, gsl_vector *v)
169 {
170 #if MGL_HAVE_GSL
171 if(!v || v->size<1) return;
172 mgl_datac_create(d, v->size,1,1);
173 for(long i=0;i<d->nx;i++) d->a[i] = v->data[i*v->stride];
174 #endif
175 }
176 //-----------------------------------------------------------------------------
mgl_datac_set_matrix(HADT d,gsl_matrix * m)177 void MGL_EXPORT mgl_datac_set_matrix(HADT d, gsl_matrix *m)
178 {
179 #if MGL_HAVE_GSL
180 if(!m || m->size1<1 || m->size2<1) return;
181 mgl_datac_create(d, m->size1,m->size2,1);
182 for(long j=0;j<d->ny;j++) for(long i=0;i<d->nx;i++)
183 d->a[i+j*d->nx] = m->data[i * m->tda + j];
184 #endif
185 }
186 //-----------------------------------------------------------------------------
mgl_datac_set_float(HADT d,const float * A,long NX,long NY,long NZ)187 void MGL_EXPORT mgl_datac_set_float(HADT d, const float *A,long NX,long NY,long NZ)
188 {
189 if(NX<=0 || NY<=0 || NZ<=0) return;
190 mgl_datac_create(d, NX,NY,NZ); if(!A) return;
191 #pragma omp parallel for
192 for(long i=0;i<NX*NY*NZ;i++) d->a[i] = A[i];
193 }
194 //-----------------------------------------------------------------------------
mgl_datac_set_double(HADT d,const double * A,long NX,long NY,long NZ)195 void MGL_EXPORT mgl_datac_set_double(HADT d, const double *A,long NX,long NY,long NZ)
196 {
197 if(NX<=0 || NY<=0 || NZ<=0) return;
198 mgl_datac_create(d, NX,NY,NZ); if(!A) return;
199 #pragma omp parallel for
200 for(long i=0;i<NX*NY*NZ;i++) d->a[i] = A[i];
201 }
202 //-----------------------------------------------------------------------------
mgl_datac_set_complex(HADT d,const mdual * A,long NX,long NY,long NZ)203 void MGL_EXPORT mgl_datac_set_complex(HADT d, const mdual *A,long NX,long NY,long NZ)
204 {
205 if(NX<=0 || NY<=0 || NZ<=0) return;
206 mgl_datac_create(d, NX,NY,NZ); if(!A) return;
207 memcpy(d->a,reinterpret_cast<const dual*>(A),NX*NY*NZ*sizeof(float));
208 }
209 //-----------------------------------------------------------------------------
mgl_datac_set_float_(uintptr_t * d,const float * A,int * NX,int * NY,int * NZ)210 void MGL_EXPORT mgl_datac_set_float_(uintptr_t *d, const float *A,int *NX,int *NY,int *NZ)
211 { mgl_datac_set_float(_DC_,A,*NX,*NY,*NZ); }
mgl_datac_set_double_(uintptr_t * d,const double * A,int * NX,int * NY,int * NZ)212 void MGL_EXPORT mgl_datac_set_double_(uintptr_t *d, const double *A,int *NX,int *NY,int *NZ)
213 { mgl_datac_set_double(_DC_,A,*NX,*NY,*NZ); }
mgl_datac_set_complex_(uintptr_t * d,const mdual * A,int * NX,int * NY,int * NZ)214 void MGL_EXPORT mgl_datac_set_complex_(uintptr_t *d, const mdual *A,int *NX,int *NY,int *NZ)
215 { mgl_datac_set_complex(_DC_,A,*NX,*NY,*NZ); }
216 //-----------------------------------------------------------------------------
mgl_datac_rearrange(HADT d,long mx,long my,long mz)217 void MGL_EXPORT mgl_datac_rearrange(HADT d, long mx,long my,long mz)
218 {
219 if(mx<1) return; // wrong mx
220 if(my<1) { my = d->nx*d->ny*d->nz/mx; mz = 1; }
221 else if(mz<1) mz = (d->nx*d->ny*d->nz)/(mx*my);
222 long m = mx*my*mz;
223 if(m==0 || m>d->nx*d->ny*d->nz) return; // too high desired dimensions
224 d->nx = mx; d->ny = my; d->nz = mz; d->NewId();
225 }
mgl_datac_rearrange_(uintptr_t * d,int * mx,int * my,int * mz)226 void MGL_EXPORT mgl_datac_rearrange_(uintptr_t *d, int *mx, int *my, int *mz)
227 { mgl_datac_rearrange(_DC_,*mx,*my,*mz); }
228 //-----------------------------------------------------------------------------
mgl_datac_to_string(HCDT d,long ns)229 std::string MGL_EXPORT mgl_datac_to_string(HCDT d, long ns)
230 {
231 std::string out;
232 const mglDataC *dd = dynamic_cast<const mglDataC*>(d);
233 if(!dd) { return mgl_data_to_string(d,ns); }
234 long nx=dd->nx, ny=dd->ny, nz=dd->nz;
235 const std::string loc = setlocale(LC_NUMERIC, "C");
236 if(ns<0 || (ns>=nz && nz>1)) for(long k=0;k<nz;k++)
237 { // save whole data
238 const mglDataC *dc = dynamic_cast<const mglDataC *>(d);
239 if(dc)
240 {
241 std::string id = dc->GetColumnId();
242 if(!id.empty()) out += "## "+id+'\n';
243 }
244 for(long i=0;i<ny;i++)
245 {
246 for(long j=0;j<nx-1;j++)
247 out+=mgl_str_num(dd->a[j+nx*(i+ny*k)])+'\t';
248 out+=mgl_str_num(dd->a[nx-1+nx*(i+ny*k)])+'\n';
249 }
250 out += "\n";
251 }
252 else
253 { // save selected slice
254 if(nz>1) for(long i=0;i<ny;i++)
255 {
256 for(long j=0;j<nx-1;j++)
257 out+=mgl_str_num(dd->a[j+nx*(i+ny*ns)])+'\t';
258 out+=mgl_str_num(dd->a[nx-1+nx*(i+ny*ns)])+'\n';
259 }
260 else if(ns<ny) for(long j=0;j<nx;j++)
261 out+=mgl_str_num(dd->a[j+nx*ns])+'\t';
262 }
263 setlocale(LC_NUMERIC, loc.c_str());
264 return out;
265 }
mgl_datac_save(HCDT d,const char * fname,long ns)266 void MGL_EXPORT mgl_datac_save(HCDT d, const char *fname,long ns)
267 {
268 FILE *fp = fopen(fname,"w");
269 if(fp) { fprintf(fp,"%s",mgl_datac_to_string(d,ns).c_str()); fclose(fp); }
270 }
mgl_datac_save_(uintptr_t * d,const char * fname,int * ns,int l)271 void MGL_EXPORT mgl_datac_save_(uintptr_t *d, const char *fname,int *ns,int l)
272 { char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0;
273 mgl_datac_save(_DC_,s,*ns); delete []s; }
274 //-----------------------------------------------------------------------------
mgl_datac_read(HADT d,const char * fname)275 int MGL_EXPORT mgl_datac_read(HADT d, const char *fname)
276 {
277 long l=1,m=1,k=1,sk=0;
278 long nb,i;
279 gzFile fp = gzopen(fname,"r");
280 if(!fp)
281 {
282 if(!d->a) mgl_datac_create(d, 1,1,1);
283 return 0;
284 }
285 char *buf = mgl_read_gz(fp), *tbuf=buf;
286 while(*buf && *buf<=' ') buf++; // remove leading spaces
287 nb = strlen(buf); gzclose(fp);
288
289 bool first=false; // space is not allowed delimiter for file with complex numbers
290 for(i=nb-1;i>=0;i--) if(buf[i]>' ') break;
291 buf[i+1]=0; nb = i+1; // remove tailing spaces
292 for(i=0;i<nb-1 && !isn(buf[i]);i++) // determine nx
293 {
294 while(buf[i]=='#') { while(!isn(buf[i]) && i<nb) i++; }
295 char ch = buf[i];
296 if(ch>' ' && !first) first=true;
297 if(strchr("[{(",ch)) sk++;
298 if(strchr("]})",ch)) sk--;
299 if(first && buf[i+1]>' ' && (ch=='\t' || ch==';' || ((ch==' '||ch==',') && sk==0) )) k++;
300 }
301 first = false;
302 for(i=0;i<nb-1;i++) // determine ny
303 {
304 char ch = buf[i];
305 if(ch=='#') while(!isn(buf[i]) && i<nb) i++;
306 if(isn(ch))
307 {
308 while(buf[i+1]=='\t') i++;
309 if(isn(buf[i+1])) {first=true; break; }
310 m++;
311 }
312 if(ch=='\f') break;
313 }
314 if(first) for(i=0;i<nb-1;i++) // determine nz
315 {
316 char ch = buf[i];
317 if(ch=='#') while(!isn(buf[i]) && i<nb) i++;
318 // if(ch=='#') com = true; // comment
319 if(isn(ch))
320 {
321 // if(com) { com=false; continue; }
322 while(buf[i+1]=='\t') i++;
323 if(isn(buf[i+1])) l++;
324 }
325 }
326 else for(i=0;i<nb-1;i++) if(buf[i]=='\f') l++;
327 mglFromStr(d,buf,k,m,l);
328 free(tbuf); return 1;
329 }
mgl_datac_read_(uintptr_t * d,const char * fname,int l)330 int MGL_EXPORT mgl_datac_read_(uintptr_t *d, const char *fname,int l)
331 { char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0;
332 int r = mgl_datac_read(_DC_, s); delete []s; return r; }
333 //-----------------------------------------------------------------------------
mgl_datac_create(HADT d,long mx,long my,long mz)334 void MGL_EXPORT mgl_datac_create(HADT d,long mx,long my,long mz)
335 {
336 d->nx = mx>0 ? mx:1; d->ny = my>0 ? my:1; d->nz = mz>0 ? mz:1;
337 if(d->a && !d->link) delete [](d->a);
338 d->a = new dual[d->nx*d->ny*d->nz];
339 d->NewId(); d->link=false;
340 memset(d->a,0,d->nx*d->ny*d->nz*sizeof(dual));
341 }
mgl_datac_create_(uintptr_t * d,int * nx,int * ny,int * nz)342 void MGL_EXPORT mgl_datac_create_(uintptr_t *d, int *nx,int *ny,int *nz)
343 { mgl_datac_create(_DC_,*nx,*ny,*nz); }
344 //-----------------------------------------------------------------------------
mgl_datac_link(HADT d,mdual * A,long mx,long my,long mz)345 void MGL_EXPORT mgl_datac_link(HADT d, mdual *A, long mx,long my,long mz)
346 {
347 if(!A) return;
348 if(!d->link && d->a) delete [](d->a);
349 d->nx = mx>0 ? mx:1; d->ny = my>0 ? my:1; d->nz = mz>0 ? mz:1;
350 d->link=true; d->a=reinterpret_cast<dual*>(A); d->NewId();
351 }
mgl_datac_link_(uintptr_t * d,mdual * A,int * nx,int * ny,int * nz)352 void MGL_EXPORT mgl_datac_link_(uintptr_t *d, mdual *A, int *nx,int *ny,int *nz)
353 { mgl_datac_link(_DC_,A,*nx,*ny,*nz); }
354 //-----------------------------------------------------------------------------
mgl_datac_read_dim(HADT d,const char * fname,long mx,long my,long mz)355 int MGL_EXPORT mgl_datac_read_dim(HADT d, const char *fname,long mx,long my,long mz)
356 {
357 if(mx<=0 || my<=0 || mz<=0) return 0;
358 gzFile fp = gzopen(fname,"r");
359 if(!fp) return 0;
360 char *buf = mgl_read_gz(fp);
361 gzclose(fp);
362 mglFromStr(d,buf,mx,my,mz);
363 free(buf); return 1;
364 }
mgl_datac_read_dim_(uintptr_t * d,const char * fname,int * mx,int * my,int * mz,int l)365 int MGL_EXPORT mgl_datac_read_dim_(uintptr_t *d, const char *fname,int *mx,int *my,int *mz,int l)
366 { char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0;
367 int r = mgl_datac_read_dim(_DC_,s,*mx,*my,*mz); delete []s; return r; }
368 //-----------------------------------------------------------------------------
mgl_datac_read_mat(HADT d,const char * fname,long dim)369 int MGL_EXPORT mgl_datac_read_mat(HADT d, const char *fname, long dim)
370 {
371 if(dim<=0 || dim>3) return 0;
372 gzFile fp = gzopen(fname,"r");
373 if(!fp) return 0;
374 long nx=1, ny=1, nz=1;
375 char *buf = mgl_read_gz(fp);
376 long nb = strlen(buf); gzclose(fp);
377
378 long j=0;
379 if(buf[j]=='#') while(!isn(buf[j])) j++; // skip comment
380 while(j<nb && buf[j]<=' ') j++;
381 if(dim==1)
382 {
383 sscanf(buf+j,"%ld",&nx);
384 while(j<nb && buf[j]!='\n') j++;
385 j++;
386 // while(buf[j]>' ') j++;
387 }
388 else if(dim==2)
389 {
390 sscanf(buf+j,"%ld%ld",&nx,&ny);
391 while(j<nb && buf[j]!='\n') j++;
392 j++;
393 char *b=buf+j;
394 long l=0;
395 for(long i=0;b[i];i++)
396 {
397 while(b[i]=='#') { while(!isn(b[i]) && b[i]) i++; }
398 if(b[i]=='\n') l++;
399 }
400 if(l==nx*ny || l==nx*ny+1) // try to read 3d data (i.e. columns of matrix nx*ny)
401 {
402 nz=ny; ny=nx; nx=1; l=0;
403 bool first = false;
404 for(long i=0;b[i] && !isn(b[i]);i++) // determine nx
405 {
406 while(b[i]=='#') { while(!isn(b[i]) && b[i]) i++; }
407 char ch = b[i];
408 if(ch>' ' && !first) first=true;
409 if(first && (ch=='\t' || ch==';') && b[i+1]!='\t') nx++;
410 }
411 }
412 }
413 else if(dim==3)
414 {
415 sscanf(buf+j,"%ld%ld%ld",&nx,&ny,&nz);
416 while(j<nb && buf[j]!='\n') j++;
417 j++;
418 }
419 mglFromStr(d,buf+j,nx,ny,nz);
420 free(buf); return 1;
421 }
mgl_datac_read_mat_(uintptr_t * d,const char * fname,int * dim,int l)422 int MGL_EXPORT mgl_datac_read_mat_(uintptr_t *d, const char *fname,int *dim,int l)
423 { char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0;
424 int r = mgl_datac_read_mat(_DC_,s,*dim); delete []s; return r; }
425 //-----------------------------------------------------------------------------
mgl_cfill_x(void * par)426 static void *mgl_cfill_x(void *par)
427 {
428 mglThreadC *t=(mglThreadC *)par;
429 long nx=t->p[0],ny=t->p[1];
430 dual *b=t->a, x1=t->b[0], dx=t->b[1];
431 char dir = t->s[0];
432 #if !MGL_HAVE_PTHREAD
433 #pragma omp parallel for
434 #endif
435 for(long i0=t->id;i0<t->n;i0+=mglNumThr)
436 {
437 if(dir=='x') b[i0] = x1+dx*mreal(i0%nx);
438 else if(dir=='y') b[i0] = x1+dx*mreal((i0/nx)%ny);
439 else if(dir=='z') b[i0] = x1+dx*mreal(i0/(nx*ny));
440 }
441 return 0;
442 }
mgl_datac_fill(HADT d,mdual x1,mdual x2,char dir)443 void MGL_EXPORT mgl_datac_fill(HADT d, mdual x1, mdual x2,char dir)
444 {
445 if(mgl_isnan(x2)) x2=x1;
446 if(dir<'x' || dir>'z') dir='x';
447 long par[2]={d->nx,d->ny};
448 dual b[2]={x1,dual(x2)-dual(x1)};
449 if(dir=='x') b[1] *= d->nx>1 ? 1./(d->nx-1):0;
450 if(dir=='y') b[1] *= d->ny>1 ? 1./(d->ny-1):0;
451 if(dir=='z') b[1] *= d->nz>1 ? 1./(d->nz-1):0;
452 mglStartThreadC(mgl_cfill_x,0,d->nx*d->ny*d->nz,d->a,b,0,par,0,0,0,&dir);
453 }
mgl_datac_fill_(uintptr_t * d,mdual * x1,mdual * x2,const char * dir,int)454 void MGL_EXPORT mgl_datac_fill_(uintptr_t *d, mdual *x1, mdual *x2, const char *dir,int)
455 { mgl_datac_fill(_DC_,*x1,*x2,*dir); }
456 //-----------------------------------------------------------------------------
mgl_datac_squeeze(HADT d,long rx,long ry,long rz,long smooth)457 void MGL_EXPORT mgl_datac_squeeze(HADT d, long rx,long ry,long rz,long smooth)
458 {
459 long kx,ky,kz, nx=d->nx, ny=d->ny, nz=d->nz;
460 dual *b;
461
462 // simple checking
463 if(rx>=nx) rx=nx-1;
464 if(rx<1) rx=1;
465 if(ry>=ny) ry=ny-1;
466 if(ry<1) ry=1;
467 if(rz>=nz) rz=nz-1;
468 if(rz<1) rz=1;
469 // new sizes
470 kx = 1+(nx-1)/rx; ky = 1+(ny-1)/ry; kz = 1+(nz-1)/rz;
471 b = new dual[kx*ky*kz];
472 if(!smooth)
473 #pragma omp parallel for collapse(3)
474 for(long k=0;k<kz;k++) for(long j=0;j<ky;j++) for(long i=0;i<kx;i++)
475 b[i+kx*(j+ky*k)] = d->a[i*rx+nx*(j*ry+ny*rz*k)];
476 else
477 #pragma omp parallel for collapse(3)
478 for(long k=0;k<kz;k++) for(long j=0;j<ky;j++) for(long i=0;i<kx;i++)
479 {
480 long dx,dy,dz,i1,j1,k1;
481 dx = (i+1)*rx<=nx ? rx : nx-i*rx;
482 dy = (j+1)*ry<=ny ? ry : ny-j*ry;
483 dz = (k+1)*rz<=nz ? rz : nz-k*rz;
484 dual s = 0;
485 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++)
486 s += d->a[i1+nx*(j1+ny*k1)];
487 b[i+kx*(j+ky*k)] = s/mreal(dx*dy*dz);
488 }
489 if(!d->link) delete [](d->a);
490 d->a=b; d->nx = kx; d->ny = ky; d->nz = kz; d->NewId(); d->link=false;
491 }
mgl_datac_squeeze_(uintptr_t * d,int * rx,int * ry,int * rz,int * smooth)492 void MGL_EXPORT mgl_datac_squeeze_(uintptr_t *d, int *rx,int *ry,int *rz,int *smooth)
493 { mgl_datac_squeeze(_DC_,*rx,*ry,*rz,*smooth); }
494 //-----------------------------------------------------------------------------
mgl_datac_extend(HADT d,long n1,long n2)495 void MGL_EXPORT mgl_datac_extend(HADT d, long n1, long n2)
496 {
497 long nx=d->nx, ny=d->ny, nz=d->nz;
498 if(nz>2 || n1==0) return;
499 long mx, my, mz;
500 dual *b=0;
501 if(n1>0) // extend to higher dimension(s)
502 {
503 n2 = n2>0 ? n2:1;
504 mx = nx; my = ny>1?ny:n1; mz = ny>1 ? n1 : n2;
505 b = new dual[mx*my*mz];
506 if(ny>1)
507 #pragma omp parallel for
508 for(long i=0;i<n1;i++) memcpy(b+i*nx*ny, d->a, nx*ny*sizeof(dual));
509 else
510 #pragma omp parallel for
511 for(long i=0;i<n1*n2;i++) memcpy(b+i*nx, d->a, nx*sizeof(dual));
512 }
513 else
514 {
515 mx = -n1; my = n2<0 ? -n2 : nx; mz = n2<0 ? nx : ny;
516 if(n2>0 && ny==1) mz = n2;
517 b = new dual[mx*my*mz];
518 if(n2<0)
519 #pragma omp parallel for collapse(2)
520 for(long j=0;j<nx;j++) for(long i=0;i<mx*my;i++)
521 b[i+mx*my*j] = d->a[j];
522 else
523 #pragma omp parallel for collapse(2)
524 for(long j=0;j<nx*ny;j++) for(long i=0;i<mx;i++)
525 b[i+mx*j] = d->a[j];
526 if(n2>0 && ny==1)
527 #pragma omp parallel for
528 for(long i=0;i<n2;i++) memcpy(b+i*mx*my, d->a, mx*my*sizeof(dual));
529 }
530 if(!d->link) delete [](d->a);
531 d->a=b; d->nx=mx; d->ny=my; d->nz=mz;
532 d->NewId(); d->link=false;
533 }
mgl_datac_extend_(uintptr_t * d,int * n1,int * n2)534 void MGL_EXPORT mgl_datac_extend_(uintptr_t *d, int *n1, int *n2)
535 { mgl_datac_extend(_DC_,*n1,*n2); }
536 //-----------------------------------------------------------------------------
mgl_datac_transpose(HADT d,const char * dim)537 void MGL_EXPORT mgl_datac_transpose(HADT d, const char *dim)
538 {
539 long nx=d->nx, ny=d->ny, nz=d->nz, n;
540 dual *b=new dual[nx*ny*nz], *a=d->a;
541 if(!strcmp(dim,"xyz")) memcpy(b,a,nx*ny*nz*sizeof(dual));
542 else if(!strcmp(dim,"xzy") || !strcmp(dim,"zy"))
543 {
544 #pragma omp parallel for collapse(3)
545 for(long j=0;j<ny;j++) for(long k=0;k<nz;k++) for(long i=0;i<nx;i++)
546 b[i+nx*(k+nz*j)] = a[i+nx*(j+ny*k)];
547 n=nz; nz=ny; ny=n;
548 }
549 else if(!strcmp(dim,"yxz") || !strcmp(dim,"yx"))
550 {
551 #pragma omp parallel for collapse(3)
552 for(long k=0;k<nz;k++) for(long i=0;i<nx;i++) for(long j=0;j<ny;j++)
553 b[j+ny*(i+nx*k)] = a[i+nx*(j+ny*k)];
554 n=nx; nx=ny; ny=n;
555 }
556 else if(!strcmp(dim,"yzx"))
557 {
558 #pragma omp parallel for collapse(3)
559 for(long k=0;k<nz;k++) for(long i=0;i<nx;i++) for(long j=0;j<ny;j++)
560 b[j+ny*(k+nz*i)] = a[i+nx*(j+ny*k)];
561 n=nx; nx=ny; ny=nz; nz=n;
562 }
563 else if(!strcmp(dim,"zxy"))
564 {
565 #pragma omp parallel for collapse(3)
566 for(long i=0;i<nx;i++) for(long j=0;j<ny;j++) for(long k=0;k<nz;k++)
567 b[k+nz*(i+nx*j)] = a[i+nx*(j+ny*k)];
568 n=nx; nx=nz; nz=ny; ny=n;
569 }
570 else if(!strcmp(dim,"zyx") || !strcmp(dim,"zx"))
571 {
572 #pragma omp parallel for collapse(3)
573 for(long i=0;i<nx;i++) for(long j=0;j<ny;j++) for(long k=0;k<nz;k++)
574 b[k+nz*(j+ny*i)] = a[i+nx*(j+ny*k)];
575 n=nz; nz=nx; nx=n;
576 }
577 memcpy(a,b,nx*ny*nz*sizeof(dual)); delete []b;
578 n=d->nx; d->nx=nx; d->ny=ny; d->nz=nz;
579 if(nx!=n) d->NewId();
580 }
mgl_datac_transpose_(uintptr_t * d,const char * dim,int l)581 void MGL_EXPORT mgl_datac_transpose_(uintptr_t *d, const char *dim,int l)
582 { char *s=new char[l+1]; memcpy(s,dim,l); s[l]=0;
583 mgl_datac_transpose(_DC_,s); delete []s; }
584 //-----------------------------------------------------------------------------
mgl_cmodify(void * par)585 static void *mgl_cmodify(void *par)
586 {
587 mglThreadC *t=(mglThreadC *)par;
588 const mglFormulaC *f = (const mglFormulaC *)(t->v);
589 long nx=t->p[0],ny=t->p[1],nz=t->p[2];
590 dual *b=t->a;
591 mreal dx,dy,dz;
592 const dual *v=t->b, *w=t->c;
593 dx=nx>1?1/(nx-1.):0; dy=ny>1?1/(ny-1.):0; dz=nz>1?1/(nz-1.):0;
594 #if !MGL_HAVE_PTHREAD
595 #pragma omp parallel for
596 #endif
597 for(long i0=t->id;i0<t->n;i0+=mglNumThr)
598 {
599 long i=i0%nx, j=((i0/nx)%ny), k=i0/(nx*ny);
600 b[i0] = f->Calc(i*dx, j*dy, k*dz, b[i0], v?v[i0]:dual(0,0), w?w[i0]:dual(0,0));
601 }
602 return 0;
603 }
mgl_datac_modify(HADT d,const char * eq,long dim)604 void MGL_EXPORT mgl_datac_modify(HADT d, const char *eq,long dim)
605 {
606 long nx=d->nx, ny=d->ny, nz=d->nz, par[3]={nx,ny,nz};
607 if(dim<=0) mgl_datac_modify_vw(d,eq,0,0); // fastest variant for whole array
608 mglFormulaC f(eq);
609 if(nz>1) // 3D array
610 {
611 par[2] -= dim; if(par[2]<0) par[2]=0;
612 mglStartThreadC(mgl_cmodify,0,nx*ny*par[2],d->a+nx*ny*dim,0,0,par,&f);
613 }
614 else // 2D or 1D array
615 {
616 par[1] -= dim; if(par[1]<0) par[1]=0;
617 mglStartThreadC(mgl_cmodify,0,nx*par[1],d->a+nx*dim,0,0,par,&f);
618 }
619 }
mgl_datac_modify_(uintptr_t * d,const char * eq,int * dim,int l)620 void MGL_EXPORT mgl_datac_modify_(uintptr_t *d, const char *eq,int *dim,int l)
621 { char *s=new char[l+1]; memcpy(s,eq,l); s[l]=0;
622 mgl_datac_modify(_DC_,s,*dim); delete []s; }
623 //-----------------------------------------------------------------------------
mgl_datac_modify_vw(HADT d,const char * eq,HCDT vdat,HCDT wdat)624 void MGL_EXPORT mgl_datac_modify_vw(HADT d, const char *eq,HCDT vdat,HCDT wdat)
625 {
626 std::wstring s = d->Name(); d->Name(L"u");
627 mglDataV x(d->nx,d->ny,d->nz, 0,1,'x'); x.Name(L"x");
628 mglDataV y(d->nx,d->ny,d->nz, 0,1,'y'); y.Name(L"y");
629 mglDataV z(d->nx,d->ny,d->nz, 0,1,'z'); z.Name(L"z");
630 mglDataV i(d->nx,d->ny,d->nz, 0,d->nx-1,'x'); i.Name(L"i");
631 mglDataV j(d->nx,d->ny,d->nz, 0,d->ny-1,'y'); j.Name(L"j");
632 mglDataV k(d->nx,d->ny,d->nz, 0,d->nz-1,'z'); k.Name(L"k");
633 mglDataV r(d->nx,d->ny,d->nz); r.Name(L"#$mgl");
634 mglData v(vdat), w(wdat); v.Name(L"v"); w.Name(L"w");
635 std::vector<mglDataA*> list;
636 list.push_back(&x); list.push_back(&y); list.push_back(&z); list.push_back(d);
637 list.push_back(&v); list.push_back(&w); list.push_back(&r);
638 list.push_back(&i); list.push_back(&j); list.push_back(&k);
639 d->Move(mglFormulaCalcC(eq,list)); d->Name(s.c_str());
640 }
mgl_datac_modify_vw_(uintptr_t * d,const char * eq,uintptr_t * v,uintptr_t * w,int l)641 void MGL_EXPORT mgl_datac_modify_vw_(uintptr_t *d, const char *eq, uintptr_t *v, uintptr_t *w,int l)
642 { char *s=new char[l+1]; memcpy(s,eq,l); s[l]=0;
643 mgl_datac_modify_vw(_DC_,s,_DA_(v),_DA_(w)); delete []s; }
644 //-----------------------------------------------------------------------------
mgl_add_file(long & kx,long & ky,long & kz,dual * & b,mglDataC * d,bool as_slice)645 static bool mgl_add_file(long &kx,long &ky, long &kz, dual *&b, mglDataC *d,bool as_slice)
646 {
647 if(as_slice && d->nz==1)
648 {
649 if(kx==d->nx && d->ny==1)
650 {
651 b = (dual *)realloc(b,kx*(ky+1)*sizeof(dual));
652 memcpy(b+kx*ky,d->a,kx*sizeof(dual)); ky++;
653 }
654 else if(kx==d->nx && ky==d->ny)
655 {
656 b = (dual *)realloc(b,kx*ky*(kz+1)*sizeof(dual));
657 memcpy(b+kx*ky*kz,d->a,kx*ky*sizeof(dual)); kz++;
658 }
659 else return false;
660 }
661 else
662 {
663 if(d->ny*d->nz==1 && ky*kz==1)
664 {
665 b = (dual *)realloc(b,(kx+d->nx)*sizeof(dual));
666 memcpy(b+kx,d->a,d->nx*sizeof(dual)); kx+=d->nx;
667 }
668 else if(kx==d->nx && kz==1 && d->nz==1)
669 {
670 b = (dual *)realloc(b,kx*(ky+d->ny)*sizeof(dual));
671 memcpy(b+kx*ky,d->a,kx*d->ny*sizeof(dual)); ky+=d->ny;
672 }
673 else if(kx==d->nx && ky==d->ny)
674 {
675 b = (dual *)realloc(b,kx*kx*(kz+d->nz)*sizeof(dual));
676 memcpy(b+kx*ky*kz,d->a,kx*ky*d->nz*sizeof(dual)); kz+=d->nz;
677 }
678 else return false;
679 }
680 return true;
681 }
682 //-----------------------------------------------------------------------------
mgl_datac_read_range(HADT dat,const char * templ,double from,double to,double step,int as_slice)683 int MGL_EXPORT mgl_datac_read_range(HADT dat, const char *templ, double from, double to, double step, int as_slice)
684 {
685 mglDataC d;
686 double t = from;
687 dual *b;
688 long kx,ky,kz,n=strlen(templ)+20;
689 char *fname = new char[n];
690
691 //read first file
692 do{ snprintf(fname,n,templ,t); fname[n-1]=0; t+= step; } while(!mgl_datac_read(&d,fname) && t<=to);
693
694 if(t>to) { delete []fname; return 0; }
695 kx = d.nx; ky = d.ny; kz = d.nz;
696 b = (dual *)malloc(kx*ky*kz*sizeof(dual));
697 memcpy(b,d.a,kx*ky*kz*sizeof(dual));
698
699 // read other files
700 for(;t<=to;t+=step)
701 {
702 snprintf(fname,n,templ,t); fname[n-1]=0;
703 if(mgl_datac_read(&d,fname))
704 if(!mgl_add_file(kx,ky,kz,b,&d,as_slice))
705 { delete []fname; free(b); return 0; }
706 }
707 dat->Set(b,kx,ky,kz);
708 delete []fname; free(b);
709 return 1;
710 }
mgl_datac_read_range_(uintptr_t * d,const char * fname,mreal * from,mreal * to,mreal * step,int * as_slice,int l)711 int MGL_EXPORT mgl_datac_read_range_(uintptr_t *d, const char *fname, mreal *from, mreal *to, mreal *step, int *as_slice,int l)
712 { char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0;
713 int r = mgl_datac_read_range(_DC_,s,*from,*to,*step,*as_slice); delete []s; return r; }
714 //-----------------------------------------------------------------------------
mgl_datac_read_all(HADT dat,const char * templ,int as_slice)715 int MGL_EXPORT mgl_datac_read_all(HADT dat, const char *templ, int as_slice)
716 {
717 #ifndef WIN32
718 mglDataC d;
719 glob_t res;
720 size_t i;
721 dual *b;
722 long kx,ky,kz;
723 glob (templ, GLOB_TILDE, NULL, &res);
724
725 //read first file
726 for(i=0;i<res.gl_pathc;i++)
727 if(mgl_datac_read(&d,res.gl_pathv[i])) break;
728
729 if(i>=res.gl_pathc) { globfree (&res); return 0; }
730 kx = d.nx; ky = d.ny; kz = d.nz;
731 b = (dual *)malloc(kx*ky*kz*sizeof(dual));
732 memcpy(b,d.a,kx*ky*kz*sizeof(dual));
733
734 for(;i<res.gl_pathc;i++)
735 {
736 if(mgl_datac_read(&d,res.gl_pathv[i]))
737 if(!mgl_add_file(kx,ky,kz,b,&d,as_slice))
738 { globfree (&res); free(b); return 0; }
739 }
740 dat->Set(b,kx,ky,kz);
741
742 globfree (&res); free(b);
743 return 1;
744 #else
745 return 0;
746 #endif
747 }
mgl_datac_read_all_(uintptr_t * d,const char * fname,int * as_slice,int l)748 int MGL_EXPORT mgl_datac_read_all_(uintptr_t *d, const char *fname, int *as_slice,int l)
749 { char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0;
750 int r = mgl_datac_read_all(_DC_,s,*as_slice); delete []s; return r; }
751 //-----------------------------------------------------------------------------
mgl_datac_real(HCDT d)752 HMDT MGL_EXPORT mgl_datac_real(HCDT d)
753 {
754 long nx=d->GetNx(),ny=d->GetNy(),nz=d->GetNz();
755 mglData *r=new mglData(nx,ny,nz);
756 const mglDataC *dd = dynamic_cast<const mglDataC*>(d);
757 if(dd)
758 #pragma omp parallel for
759 for(long i=0;i<nx*ny*nz;i++) r->a[i] = real(dd->a[i]);
760 else r->Set(d);
761 return r;
762 }
mgl_datac_real_(uintptr_t * d)763 uintptr_t MGL_EXPORT mgl_datac_real_(uintptr_t *d)
764 { return uintptr_t(mgl_datac_real(_DC_)); }
765 //-----------------------------------------------------------------------------
mgl_datac_imag(HCDT d)766 HMDT MGL_EXPORT mgl_datac_imag(HCDT d)
767 {
768 long nx=d->GetNx(),ny=d->GetNy(),nz=d->GetNz();
769 mglData *r=new mglData(nx,ny,nz);
770 const mglDataC *dd = dynamic_cast<const mglDataC*>(d);
771 if(dd)
772 #pragma omp parallel for
773 for(long i=0;i<nx*ny*nz;i++) r->a[i] = imag(dd->a[i]);
774 return r;
775 }
mgl_datac_imag_(uintptr_t * d)776 uintptr_t MGL_EXPORT mgl_datac_imag_(uintptr_t *d)
777 { return uintptr_t(mgl_datac_imag(_DC_)); }
778 //-----------------------------------------------------------------------------
mgl_datac_norm(HCDT d)779 HMDT MGL_EXPORT mgl_datac_norm(HCDT d)
780 {
781 long nx=d->GetNx(),ny=d->GetNy(),nz=d->GetNz();
782 mglData *r=new mglData(nx,ny,nz);
783 const mglDataC *dd = dynamic_cast<const mglDataC*>(d);
784 if(dd)
785 #pragma omp parallel for
786 for(long i=0;i<nx*ny*nz;i++) r->a[i] = norm(dd->a[i]);
787 else
788 #pragma omp parallel for
789 for(long i=0;i<nx*ny*nz;i++) r->a[i] = mgl_ipow(d->vthr(i),2);
790 return r;
791 }
mgl_datac_norm_(uintptr_t * d)792 uintptr_t MGL_EXPORT mgl_datac_norm_(uintptr_t *d)
793 { return uintptr_t(mgl_datac_norm(_DC_)); }
794 //-----------------------------------------------------------------------------
mgl_datac_abs(HCDT d)795 HMDT MGL_EXPORT mgl_datac_abs(HCDT d)
796 {
797 long nx=d->GetNx(),ny=d->GetNy(),nz=d->GetNz();
798 mglData *r=new mglData(nx,ny,nz);
799 const mglDataC *dd = dynamic_cast<const mglDataC*>(d);
800 if(dd)
801 #pragma omp parallel for
802 for(long i=0;i<nx*ny*nz;i++) r->a[i] = abs(dd->a[i]);
803 else
804 #pragma omp parallel for
805 for(long i=0;i<nx*ny*nz;i++) r->a[i] = fabs(d->vthr(i));
806 return r;
807 }
mgl_datac_abs_(uintptr_t * d)808 uintptr_t MGL_EXPORT mgl_datac_abs_(uintptr_t *d)
809 { return uintptr_t(mgl_datac_abs(_DC_)); }
810 //-----------------------------------------------------------------------------
mgl_datac_arg(HCDT d)811 HMDT MGL_EXPORT mgl_datac_arg(HCDT d)
812 {
813 long nx=d->GetNx(),ny=d->GetNy(),nz=d->GetNz();
814 mglData *r=new mglData(nx,ny,nz);
815 const mglDataC *dd = dynamic_cast<const mglDataC*>(d);
816 if(dd)
817 #pragma omp parallel for
818 for(long i=0;i<nx*ny*nz;i++) r->a[i] = arg(dd->a[i]);
819 return r;
820 }
mgl_datac_arg_(uintptr_t * d)821 uintptr_t MGL_EXPORT mgl_datac_arg_(uintptr_t *d)
822 { return uintptr_t(mgl_datac_arg(_DC_)); }
823 //-----------------------------------------------------------------------------
mgl_datac_set_ri(HADT d,HCDT re,HCDT im)824 void MGL_EXPORT mgl_datac_set_ri(HADT d, HCDT re, HCDT im)
825 {
826 long nx=d->GetNx(),ny=d->GetNy(),nz=d->GetNz();
827 d->Create(nx,ny,nz);
828 #pragma omp parallel for
829 for(long i=0;i<nx*ny*nz;i++) d->a[i] = dual(re->vthr(i),im->vthr(i));
830 }
mgl_datac_set_ri_(uintptr_t * d,uintptr_t * re,uintptr_t * im)831 void MGL_EXPORT mgl_datac_set_ri_(uintptr_t *d, uintptr_t *re, uintptr_t *im)
832 { mgl_datac_set_ri(_DC_,_DA_(re),_DA_(im)); }
833 //-----------------------------------------------------------------------------
mgl_datac_set_ap(HADT d,HCDT a,HCDT p)834 void MGL_EXPORT mgl_datac_set_ap(HADT d, HCDT a, HCDT p)
835 {
836 long nx=d->GetNx(),ny=d->GetNy(),nz=d->GetNz();
837 d->Create(nx,ny,nz);
838 #pragma omp parallel for
839 for(long i=0;i<nx*ny*nz;i++)
840 {
841 mreal aa=a->vthr(i), pp=p->vthr(i);
842 d->a[i] = dual(aa*cos(pp), aa*sin(pp));
843 }
844 }
mgl_datac_set_ap_(uintptr_t * d,uintptr_t * a,uintptr_t * p)845 void MGL_EXPORT mgl_datac_set_ap_(uintptr_t *d, uintptr_t *a, uintptr_t *p)
846 { mgl_datac_set_ap(_DC_,_DA_(a),_DA_(p)); }
847 //-----------------------------------------------------------------------------
848 #if MGL_HAVE_HDF5
mgl_datac_save_hdf(HCDT dat,const char * fname,const char * data,int rewrite)849 void MGL_EXPORT mgl_datac_save_hdf(HCDT dat,const char *fname,const char *data,int rewrite)
850 {
851 const mglDataC *d = dynamic_cast<const mglDataC *>(dat);
852 if(!d) { mgl_data_save_hdf(dat,fname,data,rewrite); return; }
853 hid_t hf,hd,hs;
854 hsize_t dims[4];
855 long rank = 3, res;
856 H5Eset_auto(0,0);
857 res=H5Fis_hdf5(fname);
858 if(res>0 && !rewrite) hf = H5Fopen(fname, H5F_ACC_RDWR, H5P_DEFAULT);
859 else hf = H5Fcreate(fname, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
860 if(hf<0) return;
861 if(d->nz==1 && d->ny == 1) { rank=2; dims[0]=d->nx; dims[1]=2; }
862 else if(d->nz==1) { rank=3; dims[0]=d->ny; dims[1]=d->nx; dims[2]=2; }
863 else { rank=4; dims[0]=d->nz; dims[1]=d->ny; dims[2]=d->nx; dims[3]=2; }
864 hs = H5Screate_simple(rank, dims, 0);
865 #if MGL_USE_DOUBLE
866 hid_t mem_type_id = H5T_NATIVE_DOUBLE;
867 #else
868 hid_t mem_type_id = H5T_NATIVE_FLOAT;
869 #endif
870 hd = H5Dcreate(hf, data, mem_type_id, hs, H5P_DEFAULT);
871 H5Dwrite(hd, mem_type_id, hs, hs, H5P_DEFAULT, d->a);
872 H5Dclose(hd); H5Sclose(hs); H5Fclose(hf);
873 }
874 //-----------------------------------------------------------------------------
mgl_datac_read_hdf(HADT d,const char * fname,const char * data)875 int MGL_EXPORT mgl_datac_read_hdf(HADT d,const char *fname,const char *data)
876 {
877 hid_t hf,hd,hs;
878 hsize_t dims[4];
879 long rank, res = H5Fis_hdf5(fname);
880 if(res<=0) return 0;
881 hf = H5Fopen(fname, H5F_ACC_RDONLY, H5P_DEFAULT);
882 if(hf<0) return 0;
883 hd = H5Dopen(hf,data);
884 if(hd<0) { H5Fclose(hf); return 0; }
885 hs = H5Dget_space(hd);
886 if(hs<0) { H5Dclose(hd); H5Fclose(hf); return 0; }
887 rank = H5Sget_simple_extent_ndims(hs);
888 if(rank>0 && rank<=4)
889 {
890 H5Sget_simple_extent_dims(hs,dims,0);
891 if(dims[rank-1]==2)
892 {
893 if(rank==1) { dims[2]=dims[0]=dims[1]=1; }
894 else if(rank==2) { dims[2]=dims[0]; dims[0]=dims[1]=1; }
895 else if(rank==3) { dims[2]=dims[1]; dims[1]=dims[0]; dims[0]=1; }
896 mgl_datac_create(d,dims[2],dims[1],dims[0]);
897 #if MGL_USE_DOUBLE
898 H5Dread(hd, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, d->a);
899 #else
900 H5Dread(hd, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, H5P_DEFAULT, d->a);
901 #endif
902 }
903 else if(rank<=3)
904 {
905 if(rank==1) { dims[2]=dims[0]; dims[0]=dims[1]=1; }
906 else if(rank==2) { dims[2]=dims[1]; dims[1]=dims[0]; dims[0]=1; }
907 mgl_datac_create(d,dims[2],dims[1],dims[0]);
908 long nn = dims[2]*dims[1]*dims[0];
909 mreal *a = new mreal[nn];
910 #if MGL_USE_DOUBLE
911 H5Dread(hd, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, a);
912 #else
913 H5Dread(hd, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, H5P_DEFAULT, a);
914 #endif
915 for(long i=0;i<nn;i++) d->a[i] = a[i];
916 delete []a;
917 }
918 }
919 H5Sclose(hs); H5Dclose(hd); H5Fclose(hf); return 1;
920 }
921 //-----------------------------------------------------------------------------
922 #else
mgl_datac_save_hdf(HCDT,const char *,const char *,int)923 void MGL_EXPORT mgl_datac_save_hdf(HCDT ,const char *,const char *,int )
924 { mgl_set_global_warn(_("HDF5 support was disabled. Please, enable it and rebuild MathGL.")); }
mgl_datac_read_hdf(HADT,const char *,const char *)925 int MGL_EXPORT mgl_datac_read_hdf(HADT ,const char *,const char *)
926 { mgl_set_global_warn(_("HDF5 support was disabled. Please, enable it and rebuild MathGL.")); return 0;}
927 #endif
928 //-----------------------------------------------------------------------------
mgl_datac_read_hdf_(uintptr_t * d,const char * fname,const char * data,int l,int n)929 int MGL_EXPORT mgl_datac_read_hdf_(uintptr_t *d, const char *fname, const char *data,int l,int n)
930 { char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0;
931 char *t=new char[n+1]; memcpy(t,data,n); t[n]=0;
932 int r = mgl_datac_read_hdf(_DC_,s,t); delete []s; delete []t; return r; }
mgl_datac_save_hdf_(uintptr_t * d,const char * fname,const char * data,int * rewrite,int l,int n)933 void MGL_EXPORT mgl_datac_save_hdf_(uintptr_t *d, const char *fname, const char *data, int *rewrite,int l,int n)
934 { char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0;
935 char *t=new char[n+1]; memcpy(t,data,n); t[n]=0;
936 mgl_datac_save_hdf(_DC_,s,t,*rewrite); delete []s; delete []t; }
937 //-----------------------------------------------------------------------------
mgl_datac_limit(HADT d,mreal v)938 void MGL_EXPORT mgl_datac_limit(HADT d, mreal v)
939 {
940 long n = d->GetNN();
941 dual *a = d->a;
942 #pragma omp parallel for
943 for(long i=0;i<n;i++)
944 { mreal b = abs(a[i]); if(b>v) a[i] *= v/b; }
945 }
mgl_datac_limit_(uintptr_t * d,mreal * v)946 void MGL_EXPORT mgl_datac_limit_(uintptr_t *d, mreal *v)
947 { mgl_datac_limit(_DC_, *v); }
948 //-----------------------------------------------------------------------------
949