#include #include #include #include #include #include #include #include "sysdep.h" #include "stack.h" #include "output.h" #include "builtin.h" #include "funcs.h" #include "linear.h" #include "polynom.h" #include "interval.h" #include "spread.h" #include "express.h" #include "udf.h" #include "mainloop.h" #include "edit.h" /*************************************************************************** * basic math functions (+, -, *, /) for real and complex numbers * ***************************************************************************/ static void real_add (double *x, double *y, double *z) { *z=*x+*y; } static void complex_add (double *x, double *xi, double *y, double *yi, double *z, double *zi) { *z=*x+*y; *zi=*xi+*yi; } void add (header *hd, header *hd1) /***** add add the values elementwise. *****/ { spreadf2(real_add,complex_add,interval_add,hd); } static void real_subtract (double *x, double *y, double *z) { *z=*x-*y; } static void complex_subtract (double *x, double *xi, double *y, double *yi, double *z, double *zi) { *z=*x-*y; *zi=*xi-*yi; } void subtract (header *hd, header *hd1) /***** substract substract the values elementwise. *****/ { spreadf2(real_subtract,complex_subtract,interval_sub,hd); } static void real_multiply (double *x, double *y, double *z) { *z=*x*(*y); } void complex_multiply (double *x, double *xi, double *y, double *yi, double *z, double *zi) { double h=*x * *y - *xi * *yi; *zi=*x * *yi + *xi * *y; *z=h; } void dotmultiply (header *hd, header *hd1) /***** dotmultiply multiply the values elementwise. *****/ { spreadf2(real_multiply,complex_multiply,interval_mult,hd); } static void real_divide (double *x, double *y, double *z) { #ifdef FLOAT_TEST if (*y==0.0) { *y=1e-10; error=1; } #endif *z=*x/(*y); } void complex_divide (double *x, double *xi, double *y, double *yi, double *z, double *zi) { double r,h; r=*y * *y + *yi * *yi; #ifdef FLOAT_TEST if (r==0) { r=1e-10; error=1; } #endif h=(*x * *y + *xi * *yi)/r; *zi=(*xi * *y - *x * *yi)/r; *z=h; } void dotdivide (header *hd, header *hd1) /***** dotdivide divide the values elementwise. *****/ { spreadf2(real_divide,complex_divide,interval_div,hd); } void copy_complex (double *x, double *y) { *x++=*y++; *x=*y; } /*************************************************************************** * math functions (exp, log, sqr, sin, cos, tan, asin, acos, atan) * ***************************************************************************/ static void csin (double *x, double *xi, double *z, double *zi) { *z=cosh(*xi)*sin(*x); *zi=sinh(*xi)*cos(*x); } void msin (header *hd) { spread1i(sin,csin,isin,hd); test_error("sin"); } static void ccos (double *x, double *xi, double *z, double *zi) { *z=cosh(*xi)*cos(*x); *zi=-sinh(*xi)*sin(*x); } void mcos (header *hd) { spread1i(cos,ccos,icos,hd); test_error("cos"); } static void ctan (double *x, double *xi, double *z, double *zi) { double s,si,c,ci; csin(x,xi,&s,&si); ccos(x,xi,&c,&ci); complex_divide(&s,&si,&c,&ci,z,zi); } #ifdef FLOAT_TEST static double rtan (double x) { if (cos(x)==0.0) return 1e10; return tan(x); } #endif void mtan (header *hd) { spread1i( #ifdef FLOAT_TEST rtan, #else tan, #endif ctan,itan,hd); test_error("tan"); } #ifdef FLOAT_TEST static double ratan (double x) { if (x<=-M_PI && x>=M_PI) return 1e10; else return atan(x); } #endif static void carg (double *x, double *xi, double *z) { #ifdef FLOAT_TEST if (*x==0.0 && *xi==0.0) *z=0.0; #endif *z = atan2(*xi,*x); } #ifdef FLOAT_TEST static double rlog (double x) { if (x<=0) { error=1; return 0; } else return log(x); } #endif static void cclog (double *x, double *xi, double *z, double *zi) { #ifdef FLOAT_TEST *z=rlog(sqrt(*x * *x + *xi * *xi)); #else *z=log(sqrt(*x * *x + *xi * *xi)); #endif carg(x,xi,zi); } static void catan (double *x, double *xi, double *y, double *yi) { double h,hi,g,gi,t,ti; h=1-*xi; hi=*x; g=1+*xi; gi=-*x; complex_divide(&h,&hi,&g,&gi,&t,&ti); cclog(&t,&ti,&h,&hi); *y=hi/2; *yi=-h/2; } void matan (header *hd) { spread1i( #ifdef FLOAT_TEST ratan, #else atan, #endif catan,iatan,hd); test_error("atan"); } #ifdef FLOAT_TEST static double rasin (double x) { if (x<-1 || x>1) { error=1; return 0; } else return asin(x); } #endif static void csqrt (double *x, double *xi, double *z, double *zi) { double a,r; carg(x,xi,&a); a=a/2.0; r=sqrt(sqrt(*x * *x + *xi * *xi)); *z=r*cos(a); *zi=r*sin(a); } static void casin (double *x, double *xi, double *y, double *yi) { double h,hi,g,gi; complex_multiply(x,xi,x,xi,&h,&hi); h=1-h; hi=-hi; csqrt(&h,&hi,&g,&gi); h=-*xi+g; hi=*x+gi; cclog(&h,&hi,yi,y); *yi=-*yi; } void masin (header *hd) { spread1( #ifdef FLOAT_TEST rasin, #else asin, #endif casin,hd); test_error("asin"); } #ifdef FLOAT_TEST static double racos (double x) { if (x<-1 || x>1) { error=1; return 0; } else return acos(x); } #endif static void cacos (double *x, double *xi, double *y, double *yi) { double h,hi,g,gi; complex_multiply(x,xi,x,xi,&h,&hi); h=1-h; hi=-hi; csqrt(&h,&hi,&g,&gi); hi=*xi+g; h=*x-gi; cclog(&h,&hi,yi,y); *yi=-*yi; } void macos (header *hd) { spread1( #ifdef FLOAT_TEST racos, #else acos, #endif cacos,hd); test_error("acos"); } static void cexp (double *x, double *xi, double *z, double *zi) { double r=exp(*x); *z=cos(*xi)*r; *zi=sin(*xi)*r; } #ifdef FLOAT_TEST static void rcexp (double *x, double *xi, double *z, double *zi) { double r; if (*x>=1000) { error=1; return; } r=exp(*x); *z=cos(*xi)*r; *zi=sin(*xi)*r; } #endif static inline double rexp (double x) { if (x>=1000) { error=1; return 0; } else return exp(x); } void mexp (header *hd) { #ifdef FLOAT_TEST spread1i(rexp,rcexp,iexp,hd); #else spread1i(exp,cexp,iexp,hd); #endif test_error("exp"); } static double rarg (double x) { if (x>=0) return 0.0; else return M_PI; } void mlog (header *hd) { #ifdef FLOAT_TEST spread1i(rlog,cclog,ilog,hd); #else spread1i(log,cclog,ilog,hd); #endif test_error("log"); } #ifdef FLOAT_TEST static double rsqrt (double x) { if (x<0.0) { error=1; return 0; } else return sqrt(x); } #endif void msqrt (header *hd) { spread1i( #ifdef FLOAT_TEST rsqrt, #else sqrt, #endif csqrt,isqrt,hd); test_error("sqrt"); } static void rrem (double *x, double *n, double *y) { *y=fmod(*x,*n); } void mrem (header *hd) { spreadf2(rrem,0,0,hd); test_error("mod"); } static void rmod (double *x, double *n, double *y) { if (*n==0.0) *y=*x; else { *y=fmod(*x,*n); if (*y<0) *y+=*n; } } void mmod (header *hd) { spreadf2(rmod,0,0,hd); test_error("mod"); } static void cpow (double *x, double *xi, double *y, double *yi, double *z, double *zi) { double l,li,w,wi; if (fabs(*x)0.0) *z=pow(*x,*y); else if (*x==0.0) if (*y==0.0) *z=1.0; else *z=0.0; else { n=(int)*y; if (n!=*y) { output("Illegal argument for ^\n"); error=1; return; } if (n%2) *z=-pow(-*x,n); else *z=pow(-*x,n); } } void mpower (header *hd) { spreadf2(rpow,cpow,ipow,hd); test_error("^"); } /**************************************************************************** * degree, sign, ceil, floor functions * ****************************************************************************/ static double rdegree (double x) { return x/180*M_PI; } void mdegree (header *hd) { spread1(rdegree,0,hd); test_error("signum"); } static double rsign (double x) { if (x<0) return -1; else if (x<=0) return 0; else return 1; } void msign (header *hd) { spread1(rsign,0,hd); test_error("sign"); } void mceil (header *hd) { spread1(ceil,0,hd); test_error("ceil"); } void mfloor (header *hd) { spread1(floor,0,hd); test_error("floor"); } static double rounder; static double rround (double x) { x*=rounder; if (x>0) x=floor(x+0.5); else x=-floor(-x+0.5); return x/rounder; } static void cround (double *x, double *xi, double *z, double *zi) { *z=rround(*x); *zi=rround(*xi); } static double frounder[]={1.0,10.0,100.0,1000.0,10000.0,100000.0,1000000.0, 10000000.0,100000000.0,1000000000.0,10000000000.0}; void mround (header *hd) { header *hd1; int n; hd1=next_param(hd); if (hd1) hd1=getvalue(hd1); if (error) return; if (hd1->type!=s_real) wrong_arg_in("round"); n=(int)(*realof(hd1)); if (n>0 && n<11) rounder=frounder[n]; else rounder=pow(10.0,n); spread1(rround,cround,hd); test_error("round"); } /**************************************************************************** * complex specific functions * ****************************************************************************/ static void cconj (double *x, double *xi, double *z, double *zi) { *zi=-*xi; *z=*x; } static double ident (double x) { return x; } void mconj (header *hd) { spread1(ident,cconj,hd); test_error("conj"); } static void crealpart (double *x, double *xi, double *z) { *z=*x; } void mre (header *hd) { spread1r(ident,crealpart,hd); test_error("re"); } static double zero (double x) { return 0.0; } static void cimagpart (double *x, double *xi, double *z) { *z=*xi; } void mim (header *hd) { spread1r(zero,cimagpart,hd); test_error("im"); } void marg (header *hd) { spread1r(rarg,carg,hd); test_error("arg"); } static void cxabs (double *x, double *xi, double *z) { *z=sqrt(*x * *x + *xi * *xi); } void mabs (header *hd) { spread1ir(fabs,cxabs,iabs,hd); test_error("abs"); } /**************************************************************************** * constants * ****************************************************************************/ void mpi (header *hd) { new_real(M_PI,""); } void margn (header *hd) { new_real(actargn,""); } void mtime (header *hd) { new_real(myclock(),""); } void mfree (header *hd) { new_real(ramend-endlocal,""); } #ifndef NOSHRINK void mshrink (header *hd) { header *st=hd,*result; unsigned long size; hd=getvalue(hd); if (error) return; if (hd->type!=s_real) wrong_arg_in("shrink"); if (*realof(hd)>LONG_MAX) wrong_arg_in("shrink"); size=(unsigned long)*realof(hd); if (ramend-sizetype!=s_real) wrong_arg_in("setepsilon"); result=new_real(epsilon,""); changedepsilon=epsilon=*realof(hd1); moveresult(stack,result); } void mlocalepsilon (header *hd) { header *stack=hd,*hd1,*result; hd1=getvalue(hd); if (error) return; if (hd1->type!=s_real) wrong_arg_in("localepsilon"); result=new_real(epsilon,""); epsilon=*realof(hd1); moveresult(stack,result); } void mtype (header *hd) { header *st=hd,*result; hd=getvalue(hd); if (error) return; result=new_real(hd->type,""); moveresult(st,result); } void mintersects (header *hd) { spreadf2r(0,0,iintersects,hd); test_error("intersects"); } /**************************************************************************** * compare operator * ****************************************************************************/ static void rgreater (double *x, double *y, double *z) { if (*x>*y) *z=1.0; else *z=0.0; } static void igreater (double *xa, double *xb, double *ya, double *yb, double *z) { if (*xa>*yb) *z=1.0; else *z=0.0; } void mgreater (header *hd) { header *st=hd,*hd1,*result,*hdv; hdv=getvariable(hd); if (hdv->type==s_string) { hd=getvalue(hd); hd1=getvalue(nextof(st)); if (error) return; if (hd1->type!=s_string) wrong_arg_in("=="); result=new_real(strcmp(stringof(hd),stringof(hd1))>0,""); moveresult(st,result); } else spreadf2r(rgreater,0,igreater,st); test_error("=="); } static void rless (double *x, double *y, double *z) { if (*x<*y) *z=1.0; else *z=0.0; } static void ilesst (double *xa, double *xb, double *ya, double *yb, double *z) { if (*xb<*ya) *z=1.0; else *z=0.0; } void mless (header *hd) { header *st=hd,*hd1,*result,*hdv; hdv=getvariable(hd); if (hdv->type==s_string) { hd=getvalue(hd); hd1=getvalue(nextof(st)); if (error) return; if (hd1->type!=s_string) wrong_arg_in("=="); result=new_real(strcmp(stringof(hd),stringof(hd1))<0,""); moveresult(st,result); } else spreadf2r(rless,0,ilesst,st); test_error("<"); } static void rgreatereq (double *x, double *y, double *z) { if (*x>=*y) *z=1.0; else *z=0.0; } static void igreatereq (double *xa, double *xb, double *ya, double *yb, double *z) { if (*xa>=*yb) *z=1.0; else *z=0.0; } void mgreatereq (header *hd) { header *st=hd,*hd1,*result,*hdv; hdv=getvariable(hd); if (hdv->type==s_string) { hd=getvalue(hd); hd1=getvalue(nextof(st)); if (error) return; if (hd1->type!=s_string) wrong_arg_in("=="); result=new_real(strcmp(stringof(hd),stringof(hd1))>=0,""); moveresult(st,result); } else spreadf2r(rgreatereq,0,igreatereq,st); test_error(">="); } static void rlesseq (double *x, double *y, double *z) { if (*x<=*y) *z=1.0; else *z=0.0; } static void ilesseq (double *xa, double *xb, double *ya, double *yb, double *z) { if (*xb<=*ya) *z=1.0; else *z=0.0; } void mlesseq (header *hd) { header *st=hd,*hd1,*result,*hdv; hdv=getvariable(hd); if (hdv->type==s_string) { hd=getvalue(hd); hd1=getvalue(nextof(st)); if (error) return; if (hd1->type!=s_string) wrong_arg_in("=="); result=new_real(strcmp(stringof(hd),stringof(hd1))<=0,""); moveresult(st,result); } else spreadf2r(rlesseq,0,ilesseq,st); test_error("<="); } static void requal (double *x, double *y, double *z) { if (*x==*y) *z=1.0; else *z=0.0; } static void cequal (double *x, double *xi, double *y, double *yi, double *z) { if (*x==*y && *xi==*yi) *z=1.0; else *z=0.0; } void mequal (header *hd) { header *st=hd,*hd1,*result,*hdv; hdv=getvariable(hd); if (hdv->type==s_string) { hd=getvalue(hd); hd1=getvalue(nextof(st)); if (error) return; if (hd1->type!=s_string) wrong_arg_in("=="); result=new_real(strcmp(stringof(hd),stringof(hd1))==0,""); moveresult(st,result); } else spreadf2r(requal,cequal,cequal,st); test_error("=="); } static void runequal (double *x, double *y, double *z) { if (*x!=*y) *z=1.0; else *z=0.0; } static void cunequal (double *x, double *xi, double *y, double *yi, double *z) { if (*x!=*y || *xi!=*yi) *z=1.0; else *z=0.0; } static void iunequal (double *x, double *xi, double *y, double *yi, double *z) { if (*x!=*y || *xi!=*yi) *z=1.0; else *z=0.0; } void munequal (header *hd) { header *st=hd,*hd1,*result,*hdv; hdv=getvariable(hd); if (hdv->type==s_string) { hd=getvalue(hd); hd1=getvalue(nextof(st)); if (error) return; if (hd1->type!=s_string) wrong_arg_in("=="); result=new_real(strcmp(stringof(hd),stringof(hd1))!=0,""); moveresult(st,result); } else spreadf2r(runequal,cunequal,iunequal,st); test_error("<>"); } static void raboutequal (double *x, double *y, double *z) { double rx=fabs(*x),ry=fabs(*y); if (rxtype==s_matrix) { getmatrix(hd,&r,&c,&m); result=new_cmatrix(r,c,""); if (error) return; n=(long)r*c; mr=matrixof(result)+(long)2*(n-1); m+=n-1; for (i=0; itype==s_real) { result=new_complex(*realof(hd),0.0,""); if (error) return; moveresult(st,result); } } /*************************************************************************** * events handling * ***************************************************************************/ void mwait (header *hd) { header *st=hd,*result; double now; int h; hd=getvalue(hd); if (error) return; if (hd->type!=s_real) wrong_arg_in("wait"); now=myclock(); sys_wait(*realof(hd),&h); if (h==escape) { output("Interrupt\n"); error=1; return; } now=myclock()-now; if (now>*realof(hd)) now=*realof(hd); result=new_real(now,""); if (error) return; moveresult(st,result); } void mkey (header *hd) { int scan,key; key=wait_key(&scan); if (scan==escape) { output("Interrupt\n"); error=1; return; } if (key) new_real(key,""); else new_real(scan,""); } void mcode (header *hd) { new_real(test_code(),""); } void minput (header *hd) { header *st=hd,*result; char input[1024],*oldnext; hd=getvalue(hd); if (error) return; if (hd->type!=s_string) wrong_arg_in("input"); retry: output(stringof(hd)); output("? "); nojump=1; edit(input); stringon=1; oldnext=next; next=input; result=scan_value(); next=oldnext; stringon=0; if (error) { output("Error in input!\n"); error=0; goto retry; } moveresult(st,result); } void mlineinput (header *hd) { header *st=hd,*result; char input[1024]; hd=getvalue(hd); if (error) return; if (hd->type!=s_string) wrong_arg_in("lineinput"); nojump=1; output(stringof(hd)); output("? "); edit(input); result=new_string(input,strlen(input),""); moveresult(st,result); } void minterpret (header *hd) { header *st=hd,*result; char *oldnext; hd=getvalue(hd); if (error) return; if (hd->type!=s_string) wrong_arg_in("interpret"); stringon=1; oldnext=next; next=stringof(hd); result=scan(); next=oldnext; stringon=0; if (error) { result=new_string("Error",8,""); error=0; } moveresult(st,result); } void mevaluate (header *hd) { header *st=hd,*result; char *oldnext; hd=getvalue(hd); if (error) return; if (hd->type!=s_string) wrong_arg_in("evaluate"); stringon=1; oldnext=next; next=stringof(hd); result=scan(); next=oldnext; stringon=0; if (error) { result=new_string("Syntax error!",16,""); } moveresult(st,result); } /*************************************************************************** * statistics - random numbers * ***************************************************************************/ void mfastrandom (header *hd) { header *st=hd,*result; double *m; int r,c; long k,n; hd=getvalue(hd); if (error) return; if (hd->type!=s_matrix || dimsof(hd)->r!=1 || dimsof(hd)->c!=2 || *(m=matrixof(hd))<0 || *m>=INT_MAX || *(m+1)<0 || *(m+1)>INT_MAX) wrong_arg_in("random"); r=(int)*m; c=(int)*(m+1); result=new_matrix(r,c,""); if (error) return; m=matrixof(result); n=(long)c*r; for (k=0; ktype!=s_matrix || dimsof(hd)->r!=1 || dimsof(hd)->c!=2 || *(m=matrixof(hd))<0 || *m>=INT_MAX || *(m+1)<0 || *(m+1)>INT_MAX) wrong_arg_in("normal"); r=(int)*m; c=(int)*(m+1); result=new_matrix(r,c,""); if (error) return; m=matrixof(result); n=(long)c*r; for (k=0; kINT_MAX) return 1.0; n=(int)x; for (i=2; i<=n; i++) res=res*i; return res; } void mfak (header *hd) { spread1(rfak,0,hd); test_error("fak"); } static double rlogfak (double x) { int i,n; double res=0; if (x<2 || x>INT_MAX) return 0.0; n=(int)x; for (i=2; i<=n; i++) res=res+log(i); return res; } void mlogfak (header *hd) { spread1(rlogfak,0,hd); test_error("logfak"); } static void rbin (double *x, double *y, double *z) { long i,n,m,k; double res; n=(long)*x; m=(long)*y; if (m<=0) *z=1.0; else { res=k=n-m+1; for (i=2; i<=m; i++) { k++; res=res*k/i; } *z=res; } } void mbin (header *hd) { spreadf2(rbin,0,0,hd); test_error("bin"); } static void rlogbin (double *x, double *y, double *z) { long i,n,m,k; double res; n=(long)*x; m=(long)*y; if (m<=0) *z=0.0; else { k=n-m+1; res=log(n-m+1); for (i=2; i<=m; i++) { k++; res+=log(k)-log(i); } *z=res; } } void mlogbin (header *hd) { spreadf2(rlogbin,0,0,hd); test_error("bin"); } static void rtd (double *xa, double *yf, double *zres) { double t,t1,a,b,h,z,p,y,x; int flag=0; if (fabs(*xa)=1) { a=1; b=*yf; t1=t; } else { a=*yf; b=1; t1=1/t; } y=2/(9*a); z=2/(9*b); h=pow(t1,1.0/3); x=fabs((1-z)*h-1+y)/sqrt(z*h*h+y); if (b<4) x=x*(1+0.08*x*x*x*x/(b*b*b)); h=1+x*(0.196854+x*(0.115194+x*(0.000344+x*0.019527))); p=0.5/(h*h*h*h); if (t<0.5) *zres=p/2+0.5; else *zres=1-p/2; if (flag) *zres=1-*zres; } void mtd (header *hd) { spreadf2(rtd,0,0,hd); test_error("tdis"); } static double invgauss (double a) { double t,c,d; int flag=0; if (a<0.5) { a=1-a; flag=1; } t=sqrt(-2*log(fabs(1-a))); c=2.515517+t*(0.802853+t*0.010328); d=1+t*(1.432788+t*(0.189269+t*0.001308)); if (flag) return (c/d-t); else return t-c/d; } void minvgauss (header *hd) { spread1(invgauss,0,hd); test_error("invnormaldis"); } static void invrtd (double *x, double *y, double *zres) { double z=*x,f=*y,g1,g2,g3,g4,z2; int flag=0; if (z<0.5) { flag=1; z=1-z; } z=invgauss(z); z2=z*z; g1=z*(1+z2)/4.0; g2=z*(3+z2*(16+5*z2))/96.0; g3=z*(-15+z2*(17+z2*(19+z2*3)))/384.0; g4=z*(-945+z2*(-1920+z2*(1482+z2*(776+z2*79))))/92160.0; *zres=(((g4/f+g3)/f+g2)/f+g1)/f+z; if (flag) *zres=-*zres; } void minvtd (header *hd) { spreadf2(invrtd,0,0,hd); test_error("invtdis"); } static void chi (double *xa, double *yf, double *zres) { double ch=*xa,x,y,s,t,g,j=1; long i,p,f; f=(long)*yf; if (ch=2; i-=2) j=j*i; x=pow(ch,p)*exp(-(ch/2))/j; if (f%2==0) y=1; else y=sqrt(2/(ch*M_PI)); s=1; t=1; g=f; while (t>1e-5) { g=g+2; t=t*ch/g; s=s+t; } *zres=x*y*s; } void mchi (header *hd) { spreadf2(chi,0,0,hd); test_error("chidis"); } static double f1,f2; static double rfd (double F) { double f0,a,b,h,z,p,y,x; if (F=1) return 1-p; else return p; } void mfdis (header *hd) { header *st=hd,*hd1,*hd2=0; hd1=next_param(st); if (hd1) { hd2=next_param(hd1); hd1=getvalue(hd1); } if (hd2) hd2=getvalue(hd2); if (error) return; if (hd1->type!=s_real || hd2->type!=s_real) wrong_arg_in("fdis"); f1=*realof(hd1); f2=*realof(hd2); spread1(rfd,0,hd); test_error("fdis"); } /***************************************************************************** * sorting * *****************************************************************************/ static void rmax (double *x, double *y, double *z) { if (*x>*y) *z=*x; else *z=*y; } void mmax (header *hd) { spreadf2(rmax,0,imax,hd); test_error("max"); } static void rmin (double *x, double *y, double *z) { if (*x>*y) *z=*y; else *z=*x; } void mmin (header *hd) { spreadf2(rmin,0,imin,hd); test_error("min"); } typedef struct { double val; int ind; } sorttyp; static int sorttyp_compare (const sorttyp *x, const sorttyp *y) { if (x->val>y->val) return 1; else if (x->val==y->val) return 0; else return -1; } void msort (header *hd) { header *st=hd,*result,*result1; double *m,*m1; sorttyp *t; int r,c,i; hd=getvalue(hd); if (error) return; if (hd->type!=s_real && hd->type!=s_matrix) wrong_arg_in("sort"); getmatrix(hd,&r,&c,&m); if (c==1 || r==1) result=new_matrix(r,c,""); else wrong_arg_in("sort"); if (error) return; result1=new_matrix(r,c,""); if (error) return; if (c==1) c=r; if (c==0) wrong_arg_in("sort"); if (!freeram(c*sizeof(sorttyp))) { output("Out of memory!\n"); error=600; return; } t=(sorttyp *)newram; for (i=0; ival=*m++; t->ind=i; t++; } qsort(newram,c,sizeof(sorttyp), (int (*) (const void *, const void *))sorttyp_compare); m=matrixof(result); m1=matrixof(result1); t=(sorttyp *)newram; for (i=0; ival; *m1++=t->ind+1; t++; } moveresult(st,result); moveresult(nextof(st),result1); } void mstatistics (header *hd) { header *st=hd,*hd1,*result; int i,n,r,c,k; double *m,*mr; hd=getvalue(hd); hd1=next_param(st); if (hd1) hd1=getvalue(hd1); if (error) return; if (hd1->type!=s_real || hd->type!=s_matrix) wrong_arg_in("count"); if (*realof(hd1)>INT_MAX || *realof(hd1)<2) wrong_arg_in("count"); n=(int)*realof(hd1); getmatrix(hd,&r,&c,&m); if (r!=1 && c!=1) wrong_arg_in("count"); if (c==1) c=r; result=new_matrix(1,n,""); if (error) return; mr=matrixof(result); for (i=0; i=0 && *mtype==s_real || hd->type==s_matrix) { getmatrix(hd,&r,&c,&m); result=new_matrix(r,1,""); if (error) return; mr=matrixof(result); for (i=0; imax) max=x; } *mr++=max; } } else if (hd->type==s_interval || hd->type==s_imatrix) { getmatrix(hd,&r,&c,&m); result=new_imatrix(r,1,""); if (error) return; mr=matrixof(result); for (i=0; itype==s_real || hd->type==s_matrix) { getmatrix(hd,&r,&c,&m); result=new_matrix(r,1,""); if (error) return; mr=matrixof(result); for (i=0; itype==s_interval || hd->type==s_imatrix) { getmatrix(hd,&r,&c,&m); result=new_imatrix(r,1,""); if (error) return; mr=matrixof(result); for (i=0; itype==s_complex || hd->type==s_cmatrix) result=new_real(1.0,""); else result=new_real(0.0,""); if (error) return; moveresult(st,result); } void misreal (header *hd) { header *st=hd,*result; hd=getvalue(hd); if (error) return; if (hd->type==s_real || hd->type==s_matrix) result=new_real(1.0,""); else result=new_real(0.0,""); if (error) return; moveresult(st,result); } void misfunction (header *hd) { header *st=hd,*result; hd=getvalue(hd); if (error) return; if (hd->type==s_string && (searchudf(stringof(hd))!=0 || find_builtin(stringof(hd))!=0)) result=new_real(1.0,""); else result=new_real(0.0,""); if (error) return; moveresult(st,result); } void misvar (header *hd) { header *st=hd,*result; hd=getvalue(hd); if (error) return; if (hd->type==s_string && searchvar(stringof(hd))!=0) result=new_real(1.0,""); else result=new_real(0.0,""); if (error) return; moveresult(st,result); } void misinterval (header *hd) { header *st=hd,*result; hd=getvalue(hd); if (error) return; if (hd->type==s_interval || hd->type==s_imatrix) result=new_real(1.0,""); else result=new_real(0.0,""); if (error) return; moveresult(st,result); } /**************************************************************************** * rounding * ****************************************************************************/ void mchar (header *hd) { header *st=hd,*result; hd=getvalue(hd); if (error) return; if (hd->type!=s_real) wrong_arg_in("char"); result=new_string("a",1,""); if (error) return; *stringof(result)=(char)*realof(hd); moveresult(st,result); } void mascii (header *hd) { header *st=hd,*result; hd=getvalue(hd); if (error) return; if (hd->type!=s_string) wrong_arg_in("ascii"); result=new_real(*stringof(hd),""); if (error) return; moveresult(st,result); } void merror (header *hd) { hd=getvalue(hd); if (error) return; if (hd->type!=s_string) wrong_arg_in("error"); output1("Error : %s\n",stringof(hd)); error=301; } extern int preventoutput; void merrlevel (header *hd) { header *st=hd,*res; char *oldnext; int en; hd=getvalue(hd); if (error) return; if (hd->type!=s_string) wrong_arg_in("errorlevel"); stringon=1; oldnext=next; next=stringof(hd); res=new_real(0,""); preventoutput=1; scan(); preventoutput=0; next=oldnext; stringon=0; en=error; error=0; if (en) { *realof(res)=en; moveresult(st,res); } else { moveresult1(st,res); } } void mprintf (header *hd) { header *st=hd,*hd1,*result; char string[1024]; hd1=next_param(hd); hd=getvalue(hd); hd1=getvalue(hd1); if (error) return; if (hd->type!=s_string || hd1->type!=s_real) wrong_arg_in("printf"); sprintf(string,stringof(hd),*realof(hd1)); result=new_string(string,strlen(string),""); if (error) return; moveresult(st,result); } void msetkey (header *hd) /***** set a function key *****/ { header *st=hd,*hd1,*result; char *p; int n; hd=getvalue(hd); if (error) return; hd1=nextof(st); hd1=getvalue(hd1); if (error) return; if (hd->type!=s_real || hd1->type!=s_string) wrong_arg_in("setkey"); n=(int)(*realof(hd))-1; p=stringof(hd1); if (n<0 || n>=10 || strlen(p)>63) wrong_arg_in("setkey"); result=new_string(fktext[n],strlen(fktext[n]),""); if (error) return; strcpy(fktext[n],p); moveresult(st,result); } void mcd (header *hd) { header *st=hd,*result; char *path; hd=getvalue(hd); if (error) return; if (hd->type!=s_string) wrong_arg_in("cd"); path=cd(stringof(hd)); result=new_string(path,strlen(path),""); moveresult(st,result); } static char **search_entries=NULL; static int search_count=0,search_current=0; void mdir (header *hd) { header *st=hd,*result; // char *name; hd=getvalue(hd); if (error) return; if (hd->type!=s_string) wrong_arg_in("dir"); if (search_entries) { int i; for (i=0;itype!=s_real) wrong_arg_in("args"); n=(int)*realof(hd); if (n<1) wrong_arg_in("args"); if (n>actargn) { newram=(char *)st; return; } result=(header *)startlocal; i=1; while (iactargn) n=actargn; result=(header *)startlocal; i=1; while (iname,strlen(hd->name),""); moveresult(st,result); } #ifdef WAVES void mplaywav (header *hd) { header *st=hd; hd=getvalue(hd); if (error) return; if (hd->type!=s_string) wrong_arg_in("playwave"); sys_playwav(stringof(hd)); moveresult(st,hd); } #endif