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