Ejemplo n.º 1
0
//-----------------------------------------------------------------------------
HADT MGL_EXPORT mgl_datac_column(HCDT dat, const char *eq)
{
	const mglData *dd=dynamic_cast<const mglData *>(dat);
	std::vector<mglDataA*> list;
	if(dd && dd->id.length()>0)	for(size_t i=0;i<dd->id.length();i++)
	{
		mglDataT *col = new mglDataT(*dat);
		col->SetInd(i,dd->id[i]);
		list.push_back(col);
	}
	const mglDataC *dc=dynamic_cast<const mglDataC *>(dat);
	if(dc && dc->id.length()>0)	for(size_t i=0;i<dc->id.length();i++)
	{
		mglDataT *col = new mglDataT(*dat);
		col->SetInd(i,dc->id[i]);
		list.push_back(col);
	}
	if(list.size()==0)	return 0;	// no named columns
	mglDataV *t = new mglDataV(dat->GetNy(),dat->GetNz());
	t->s=L"#$mgl";	list.push_back(t);
	mglDataC *r = new mglDataC;
	r->Set(mglFormulaCalcC(eq,list));
	for(size_t i=0;i<list.size();i++)	delete list[i];
	return r;
}
Ejemplo n.º 2
0
//-----------------------------------------------------------------------------
void MGL_EXPORT mgl_datac_fill_eq(HMGL gr, HADT d, const char *eq, HCDT vdat, HCDT wdat, const char *opt)
{
	if(vdat && vdat->GetNN()!=d->GetNN())	return;	// incompatible dimensions
	if(wdat && wdat->GetNN()!=d->GetNN())	return;
	gr->SaveState(opt);
	std::wstring s = d->Name();	d->Name(L"u");
	mglDataV x(d->nx,d->ny,d->nz, gr->Min.x,gr->Max.x,'x');	x.Name(L"x");
	mglDataV y(d->nx,d->ny,d->nz, gr->Min.y,gr->Max.y,'y');	y.Name(L"y");
	mglDataV z(d->nx,d->ny,d->nz, gr->Min.z,gr->Max.z,'z');	z.Name(L"z");
	mglDataV i(d->nx,d->ny,d->nz, 0,d->nx-1,'x');	i.Name(L"i");
	mglDataV j(d->nx,d->ny,d->nz, 0,d->ny-1,'y');	j.Name(L"j");
	mglDataV k(d->nx,d->ny,d->nz, 0,d->nz-1,'z');	k.Name(L"k");
	mglDataV r(d->nx,d->ny,d->nz);	r.Name(L"#$mgl");
	mglData v(vdat), w(wdat);	v.Name(L"v");	w.Name(L"w");
	std::vector<mglDataA*> list;
	list.push_back(&x);	list.push_back(&y);	list.push_back(&z);	list.push_back(&r);
	list.push_back(d);	list.push_back(&v);	list.push_back(&w);
	list.push_back(&i);	list.push_back(&j);	list.push_back(&k);
	d->Move(mglFormulaCalcC(eq,list));	d->Name(s.c_str());	gr->LoadState();
}
Ejemplo n.º 3
0
//-----------------------------------------------------------------------------
HADT MGL_EXPORT mgl_datac_momentum(HCDT dat, char dir, const char *how)
{
	if(!how || !(*how) || !strchr("xyz",dir))	return 0;
	long nx=dat->GetNx(),ny=dat->GetNy(),nz=dat->GetNz();
	mglDataV x(nx,ny,nz, 0,1,'x');	x.s=L"x";
	mglDataV y(nx,ny,nz, 0,1,'y');	y.s=L"y";
	mglDataV z(nx,ny,nz, 0,1,'z');	z.s=L"z";
	mglDataC u(dat);	u.s=L"u";	// NOTE slow !!!
	std::vector<mglDataA*> list;
	list.push_back(&x);	list.push_back(&y);	list.push_back(&z);	list.push_back(&u);
	mglDataC res=mglFormulaCalcC(how,list);

	mglDataC *b=0;
	if(dir=='x')
	{
		b=new mglDataC(nx);
#pragma omp parallel for
		for(long i=0;i<nx;i++)
		{
			register dual i1=0,i0=0;
			for(long j=0;j<ny*nz;j++)
			{
				register dual u=dat->vthr(i+nx*j);
				i0 += u;	i1 += u*res.a[i+nx*j];
			}
			b->a[i] = i0!=mreal(0) ? i1/i0 : 0;
		}
	}
	if(dir=='y')
	{
		b=new mglDataC(ny);
#pragma omp parallel for
		for(long i=0;i<ny;i++)
		{
			register dual i1=0,i0=0;
			for(long k=0;k<nz;k++)	for(long j=0;j<nx;j++)
			{
				register dual u=dat->v(j,i,k);
				i0 += u;	i1 += u*res.a[j+nx*(i+ny*k)];
			}
			b->a[i] = i0!=mreal(0) ? i1/i0 : 0;
		}
	}
	if(dir=='z')
	{
		long nn=nx*ny;
		b=new mglDataC(nz);
#pragma omp parallel for
		for(long i=0;i<nz;i++)
		{
			register dual i1=0,i0=0;
			for(long j=0;j<nn;j++)
			{
				register dual u=dat->vthr(j+nn*i);
				i0 += u;	i1 += u*res.a[j+nn*i];
			}
			b->a[i] = i0!=mreal(0) ? i1/i0 : 0;
		}
	}
	return b;
}
Ejemplo n.º 4
0
//-----------------------------------------------------------------------------
// return values: 0 - OK, 1 - wrong arguments, 2 - wrong command, 3 - string too long, 4 -- unclosed string
int mglParser::Parse(mglGraph *gr, std::wstring str, long pos)
{
	if(Stop || gr->NeedStop())	return 0;
	curGr = gr->Self();
	std::wstring arg[1024];
	str=mgl_trim_ws(str);
	long n,k=0,m=0,mm=0,res;
	// try parse ':' -- several commands in line
	for(n=0;n<long(str.length());n++)
	{
		if(str[n]=='\'' && (n==0 || str[n-1]!='\\'))	k++;
		if(k%2)	continue;
		if(str[n]=='(')	m++;	if(str[n]==')')	m--;
		if(str[n]=='{')	mm++;	if(str[n]=='}')	mm--;
		if(str[n]=='#')	break;
		if((str[n]==':' || str[n]=='\n') && k%2==0 && m==0 && mm==0)
		{
			res=Parse(gr,str.substr(0,n),pos);
			if(!res)	res=Parse(gr,str.substr(n+1),pos);
			return res;
		}
	}
	if(k%2 || m || mm)	return 4;	// strings is not closed
	// define parameters or start cycle
	res = ParseDef(str);	if(res)	return res-1;
	// parse arguments (parameters $1, ..., $9)
	PutArg(str,false);	str=mgl_trim_ws(str);

	std::wstring opt;
	for(k=0;k<1024;k++)	// parse string to substrings (by spaces)
	{
		n = mglFindArg(str);
		if(n<1)	// this is option
		{
			if(str[-n]==';')	opt = str.substr(-n+1);
			if(n<0)	str = str.substr(0,-n);
			break;
		}
		arg[k] = str.substr(0,n);
		str = mgl_trim_ws(str.substr(n+1));
	}
	// try to find last argument
	if(str[0]!=0 && str[0]!='#' && str[0]!=';')	{	arg[k] = str;	k++;	}
	if(k<1) n =0;
	else
	{
		// fill arguments by its values
		mglArg *a = new mglArg[k];
		FillArg(gr, k, arg, a);
		// execute first special (program-flow-control) commands
		if(!skip() && !arg[0].compare(L"stop"))
		{	Stop = true;	delete []a;	return 0;	}
		if(!arg[0].compare(L"func"))
		{	Stop = true;	delete []a;	return 0;	}
		n = FlowExec(gr, arg[0].c_str(),k-1,a);
		if(n)		{	delete []a;	return n-1;	}
		if(skip())	{	delete []a;	return 0;	}
		if(!arg[0].compare(L"load"))
		{
			int n = a[0].type==1?0:1;
			a[0].s.assign(a[0].w.begin(),a[0].w.end());
			if(!n)	mgl_parser_load(this,a[0].s.c_str());
			delete []a;	return n;
		}
		if(!arg[0].compare(L"define"))
		{
			if(k==3)
			{
				DeleteVar(arg[1].c_str());	// force to delete variable with the same name
				mglNum *v=AddNum(arg[1].c_str());
				if(arg[2][0]=='!')	// complex number is added
				{	HADT dd = mglFormulaCalcC(arg[2].substr(1),this, DataList);
					v->d=NAN;	v->c = dd->a[0];	delete dd;	}
				else
				{	HMDT dd = mglFormulaCalc(arg[2],this, DataList);
					v->c = v->d = dd->a[0];	delete dd;	}
			}
			delete []a;	return k==3?0:1;
		}
		if(!arg[0].compare(L"rkstep"))
		{
			int res=1;
			if(k>2 && a[0].type==1 && a[1].type==1)
			{
				std::wstring a1 = arg[1], a2=arg[2];	res = 0;
				if(a1[0]=='\'')	a1 = a1.substr(1,a1.length()-2);
				if(a2[0]=='\'')	a2 = a2.substr(1,a2.length()-2);
				mgl_rk_step_w(this, a1.c_str(), a2.c_str(), (k>=3 && a[2].type==2)?a[2].v:1);
			}
			delete []a;	return res;
		}
		if(!arg[0].compare(L"call"))
		{
			n = 1;
			if(a[0].type==1)
			{
				int na=0;
				a[0].s.assign(a[0].w.begin(),a[0].w.end());
				n=-IsFunc(a[0].w.c_str(),&na);
				if(n && k!=na+2)
				{
					char buf[64];
					snprintf(buf,64,"Bad arguments for %ls: %ld instead of %d\n", a[0].w.c_str(),k-2,na);
					buf[63]=0;	gr->SetWarn(-1,buf);	n = 1;
				}
				else if(n)
				{
					mglFnStack fn;			fn.pos = pos;
					for(int i=0;i<10;i++)	{	fn.par[i] = par[i];	par[i]=L"";	}
					for(int i=1;i<k-1;i++)	AddParam(i,arg[i+1].c_str());
					fn_stack.push_back(fn);	n--;
				}
				else if(AllowFileIO)	// disable external scripts if AllowFileIO=false
				{
					FILE *fp = fopen(a[0].s.c_str(),"rt");
					if(fp)
					{
						register int i;
						mglParser *prs = new mglParser(AllowSetSize);
						prs->DataList.swap(DataList);	prs->NumList.swap(NumList);	prs->Cmd=Cmd;
						for(i=10;i<30;i++)	prs->AddParam(i,par[i].c_str());
						prs->Execute(gr,fp);
						for(i=10;i<30;i++)	AddParam(i,prs->par[i].c_str());
						DataList.swap(prs->DataList);	NumList.swap(prs->NumList);
						prs->Cmd=0;	delete prs;	fclose(fp);
					}
					else	n=1;
				}
			}
			delete []a;	return n;
		}
		if(!arg[0].compare(L"for"))
		{
			n = 1;
			char ch = arg[1][0];
			int r = ch-'0';
			if(ch>='a' && ch<='z')	r = 10+ch-'a';
//			int r = int(a[0].v);
			if(arg[1][1]==0 && (r>=0 && r<40))
			{
				if(a[1].type==0)
				{
					n=0;		fval[r] = *(a[1].d);
					fval[r].nx *= fval[r].ny*fval[r].nz;
				}
				else if(a[1].type==2 && a[2].type==2 && a[2].v>a[1].v)
				{
					mreal step = a[3].type==2?a[3].v:1;
					mm = int(step>0 ? (a[2].v-a[1].v)/step : 0);
					if(mm>0)
					{
						n=0;	fval[r].Create(mm+1);
						for(int ii=0;ii<mm+1;ii++)
							fval[r].a[ii] = a[1].v + step*ii;
					}
				}
				if(n==0)
				{
					for(int i=39;i>0;i--)
					{	for_stack[i]=for_stack[i-1];	if_for[i]=if_for[i-1];	}
					for_stack[0] = r+1;		fval[r].nz = pos;	if_for[0]=if_pos;
					wchar_t buf[32];		mglprintf(buf,32,L"%g",fval[r].a[0]);
					AddParam(r, buf);	fval[r].ny = 1;
				}
			}
			delete []a;	return n;
		}
		// alocate new arrays and execute the command itself
		n = PreExec(gr, k, arg, a);
		if(n>0)	n--;
		else if(!arg[0].compare(L"setsize") && !AllowSetSize)	n = 2;
		else	n = Exec(gr, arg[0].c_str(),k-1,a, arg[1].c_str(), opt.c_str());
		delete []a;
	}
	// delete temporary data arrays
	for(size_t i=0;i<DataList.size();i++)	if(DataList[i] && DataList[i]->temp)
	{	mglDataA *u=DataList[i];	DataList[i]=0;	delete u;	}
	return n;
}
Ejemplo n.º 5
0
//-----------------------------------------------------------------------------
// convert substrings to arguments
void mglParser::FillArg(mglGraph *gr, int k, std::wstring *arg, mglArg *a)
{
	register long n;
	for(n=1;n<k;n++)
	{
		mglDataA *v;	mglNum *f;
		a[n-1].type = -1;
		if(arg[n][0]=='|')	a[n-1].type = -1;
		else if(arg[n][0]=='\'')	// this is string (simplest case)
		{
			a[n-1].type = 1;
			std::wstring &w=arg[n],f;
			wchar_t buf[32];
			long i,i1,ll=w.length();
			for(i=1;i<ll;i++)
			{
				if(w[i]=='\'')
				{
					if(i==ll-1)	continue;
					i++;	i1 = i;
					if(w[i1]==',')	i1++;
					if(w[i1]==0)	continue;
					for(;i<ll && w[i]!='\'';i++);
					if(i>i1)
					{
						if(w[i1]=='!')
						{
							HADT d = mglFormulaCalcC(w.substr(i1+1,i-i1-(w[i]=='\''?1:0)), this, DataList);
							mreal di = imag(d->a[0]), dr = real(d->a[0]);
							if(di>0)	mglprintf(buf,32,L"%g+%gi",dr,di);
							else if(di<0)	mglprintf(buf,32,L"%g-%gi",dr,-di);	// TODO use \u2212 ???
							else	mglprintf(buf,32,L"%g",dr);
							a[n-1].w += buf;	delete d;
						}
						else
						{
							HMDT d = mglFormulaCalc(w.substr(i1,i-i1-(w[i]=='\''?1:0)), this, DataList);
							mglprintf(buf,32,L"%g",d->a[0]);	a[n-1].w += buf;	delete d;
						}
					}
				}
				else	a[n-1].w += w[i];
			}
		}
		else if(arg[n][0]=='{')
		{	// this is temp data
			mglData *u=new mglData;
			std::wstring s = arg[n].substr(1,arg[n].length()-2);
			a[n-1].w = u->s = L"/*"+s+L"*/";
			a[n-1].type = 0;
			ParseDat(gr, s, *u);	a[n-1].d = u;
			u->temp=true;	DataList.push_back(u);
		}
		else if((v = FindVar(arg[n].c_str()))!=0)	// try to find normal variables (for data creation)
		{	a[n-1].type=0;	a[n-1].d=v;	a[n-1].w=v->s;	}
		else if((f = FindNum(arg[n].c_str()))!=0)	// try to find normal number (for data creation)
		{	a[n-1].type=2;	a[n-1].d=0;	a[n-1].v=f->d;	a[n-1].c=f->c;	a[n-1].w = f->s;	}
		else if(arg[n][0]=='!')	// complex array is asked
		{	// parse all numbers and formulas by unified way
			HADT d = mglFormulaCalcC(arg[n].substr(1), this, DataList);
			if(d->GetNN()==1)
			{
				if(CheckForName(arg[n].substr(1)))
				{	a[n-1].type = 2;	a[n-1].v = d->v(0);	a[n-1].c = d->a[0];	}
				else
				{	a[n-1].type = 0;	a[n-1].d = AddVar(arg[n].c_str());	}
				delete d;
			}
			else
			{
				a[n-1].w = L"/*"+arg[n]+L"*/";
				d->temp=true;	DataList.push_back(d);
				a[n-1].type = 0;	a[n-1].d = d;
			}
		}
		else
		{	// parse all numbers and formulas by unified way
			HMDT d = mglFormulaCalc(arg[n], this, DataList);
			if(d->GetNN()==1)
			{
				if(CheckForName(arg[n]))
				{	a[n-1].type = 2;	a[n-1].c = a[n-1].v = d->v(0);	}
				else
				{	a[n-1].type = 0;	a[n-1].d = AddVar(arg[n].c_str());	}
				delete d;
			}
			else
			{
				a[n-1].w = L"/*"+arg[n]+L"*/";
				d->temp=true;	DataList.push_back(d);
				a[n-1].type = 0;	a[n-1].d = d;
			}
		}
	}
}
Ejemplo n.º 6
0
void MGL_EXPORT mgl_rk_step_w(HMPR pr, const wchar_t *Eqs, const wchar_t *Vars, mreal dt)
{
	const std::wstring eqs(Eqs);
	const std::wstring vars(Vars);
	std::vector<mglRKdat> rkv;
	size_t iv=0,jv=0,ie=0,je=0;
	while(1)
	{
		iv = vars.find(';',jv);	ie = eqs.find(';',je);
		mglDataA *vv=mgl_parser_find_varw(pr,vars.substr(jv,iv-jv).c_str());
		std::wstring eq = eqs.substr(je,ie-je).c_str();
		if(vv)	rkv.push_back(mglRKdat(vv, eq ));
		jv = iv+1;	je = ie+1;
		if(iv==std::wstring::npos || ie==std::wstring::npos)	break;
	}
	for(size_t i=0;i<rkv.size();i++)	rkv[i].allocate();
	mreal hh = dt/2;
	for(size_t i=0;i<rkv.size();i++)
	{
		mglRKdat &rk = rkv[i];
		if(rk.cmplx)	rk.c1.Move(mglFormulaCalcC(rk.e, pr, pr->DataList));
		else	rk.d1.Move(mglFormulaCalc(rk.e, pr, pr->DataList));
	}
	for(size_t i=0;i<rkv.size();i++)
	{
		mglRKdat &rk = rkv[i];
		if(rk.cc)
		{
			long n = rk.cc->GetNN();	dual a = hh*rk.c1.a[0];
			if(rk.c1.GetNN()==n)
#pragma omp parallel for
				for(long j=0;j<n;j++)	rk.cc->a[j] = rk.cin.a[j] + hh*rk.c1.a[j];
			else
#pragma omp parallel for
				for(long j=0;j<n;j++)	rk.cc->a[j] = rk.cin.a[j] + a;
		}
		if(rk.dd)
		{
			long n = rk.dd->GetNN();	mreal a = hh*rk.d1.a[0];
			if(rk.d1.GetNN()==n)
#pragma omp parallel for
				for(long j=0;j<n;j++)	rk.dd->a[j] = rk.din.a[j] + hh*rk.d1.a[j];
			else
#pragma omp parallel for
				for(long j=0;j<n;j++)	rk.dd->a[j] = rk.din.a[j] + a;
		}
	}

	for(size_t i=0;i<rkv.size();i++)
	{
		mglRKdat &rk = rkv[i];
		if(rk.cmplx)	rk.c2.Move(mglFormulaCalcC(rk.e, pr, pr->DataList));
		else	rk.d2.Move(mglFormulaCalc(rk.e, pr, pr->DataList));
	}
	for(size_t i=0;i<rkv.size();i++)
	{
		mglRKdat &rk = rkv[i];
		if(rk.cc)
		{
			long n = rk.cc->GetNN();	dual a = hh*rk.c2.a[0];
			if(rk.c2.GetNN()==n)
#pragma omp parallel for
				for(long j=0;j<n;j++)	rk.cc->a[j] = rk.cin.a[j] + hh*rk.c2.a[j];
			else
#pragma omp parallel for
				for(long j=0;j<n;j++)	rk.cc->a[j] = rk.cin.a[j] + a;
		}
		if(rk.dd)
		{
			long n = rk.dd->GetNN();	mreal a = hh*rk.d2.a[0];
			if(rk.d2.GetNN()==n)
#pragma omp parallel for
				for(long j=0;j<n;j++)	rk.dd->a[j] = rk.din.a[j] + hh*rk.d2.a[j];
			else
#pragma omp parallel for
				for(long j=0;j<n;j++)	rk.dd->a[j] = rk.din.a[j] + a;
		}
	}

	for(size_t i=0;i<rkv.size();i++)
	{
		mglRKdat &rk = rkv[i];
		if(rk.cmplx)	rk.c3.Move(mglFormulaCalcC(rk.e, pr, pr->DataList));
		else	rk.d3.Move(mglFormulaCalc(rk.e, pr, pr->DataList));
	}
	for(size_t i=0;i<rkv.size();i++)
	{
		mglRKdat &rk = rkv[i];
		if(rk.cc)
		{
			long n = rk.cc->GetNN();	dual a = dt*rk.c3.a[0];
			if(rk.c3.GetNN()==n)
#pragma omp parallel for
				for(long j=0;j<n;j++)	rk.cc->a[j] = rk.cin.a[j] + dt*rk.c3.a[j];
			else
#pragma omp parallel for
				for(long j=0;j<n;j++)	rk.cc->a[j] = rk.cin.a[j] + a;
		}
		if(rk.dd)
		{
			long n = rk.dd->GetNN();	mreal a = dt*rk.d3.a[0];
			if(rk.d3.GetNN()==n)
#pragma omp parallel for
				for(long j=0;j<n;j++)	rk.dd->a[j] = rk.din.a[j] + dt*rk.d3.a[j];
			else
#pragma omp parallel for
				for(long j=0;j<n;j++)	rk.dd->a[j] = rk.din.a[j] + a;
		}
	}

	for(size_t i=0;i<rkv.size();i++)
	{
		mglRKdat &rk = rkv[i];
		if(rk.cmplx)	rk.c4.Move(mglFormulaCalcC(rk.e, pr, pr->DataList));
		else	rk.d4.Move(mglFormulaCalc(rk.e, pr, pr->DataList));
	}
	for(size_t i=0;i<rkv.size();i++)
	{
		mglRKdat &rk = rkv[i];
		if(rk.cc)
		{
			long n = rk.cc->GetNN();
			dual a = (rk.c1.a[0]+rk.c2.a[0]+mreal(2)*(rk.c3.a[0]+rk.c4.a[0]))*(dt/6);
			if(rk.c1.GetNN()==n)
#pragma omp parallel for
				for(long j=0;j<n;j++)	rk.cc->a[j] = rk.cin.a[j] + (rk.c1.a[j]+rk.c2.a[j]+mreal(2)*(rk.c3.a[j]+rk.c4.a[j]))*(dt/6);
			else
#pragma omp parallel for
				for(long j=0;j<n;j++)	rk.cc->a[j] = rk.cin.a[j] + a;
		}
		if(rk.dd)
		{
			long n = rk.dd->GetNN();
			mreal a = (rk.d1.a[0]+rk.d2.a[0]+2*(rk.d3.a[0]+rk.d4.a[0]))*(dt/6);
			if(rk.d1.GetNN()==n)
#pragma omp parallel for
				for(long j=0;j<n;j++)	rk.dd->a[j] = rk.din.a[j] + (rk.d1.a[j]+rk.d2.a[j]+2*(rk.d3.a[j]+rk.d4.a[j]))*(dt/6);
			else
#pragma omp parallel for
				for(long j=0;j<n;j++)	rk.dd->a[j] = rk.din.a[j] + a;
		}
	}
}
Ejemplo n.º 7
0
HADT MGL_EXPORT mgl_parser_calc_complexw(HMPR pr, const wchar_t *formula)
{	return mglFormulaCalcC(formula,pr, pr->DataList);	}