/***** * gsl.cc * 2010/05/19 * * Initialize gsl builtins. *****/ #if defined(HAVE_CONFIG_H) #include "config.h" #endif #ifdef HAVE_LIBGSL #include "vm.h" #include "types.h" #include "entry.h" #include "builtin.h" #include "record.h" #include "stack.h" #include "errormsg.h" #include "array.h" #include "triple.h" #include "callable.h" #include #include #include #include #include #include #include #include "opsymbols.h" #ifndef NOSYM #include "gsl.symbols.h" #endif namespace trans { using types::formal; using types::primVoid; using types::primInt; using types::primReal; using types::primPair; using types::primTriple; using types::primString; using types::IntArray; using types::realArray; using types::stringArray; using vm::stack; using vm::array; using vm::pop; using vm::error; using run::copyArrayC; using run::copyCArray; using camp::pair; using camp::triple; const char* GSLrngnull = "GSL random number generator not initialized"; const char* GSLinvalid = "invalid argument"; bool GSLerror=false; types::dummyRecord *GSLModule; types::record *getGSLModule() { return GSLModule; } inline void checkGSLerror() { if(GSLerror) { GSLerror=false; throw handled_error(); } } template void realRealGSL(stack *s) { double x=pop(s); s->push(func(x)); checkGSLerror(); } template void realRealDOUBLE(stack *s) { double x=pop(s); s->push(func(x,GSL_PREC_DOUBLE)); checkGSLerror(); } template void realRealRealDOUBLE(stack *s) { double y=pop(s); double x=pop(s); s->push(func(x,y,GSL_PREC_DOUBLE)); checkGSLerror(); } template void realIntGSL(stack *s) { s->push(func(unsignedcast(pop(s)))); checkGSLerror(); } template void realIntRealGSL(stack *s) { double x=pop(s); s->push(func(intcast(pop(s)),x)); checkGSLerror(); } template void realRealRealGSL(stack *s) { double x=pop(s); double n=pop(s); s->push(func(n,x)); checkGSLerror(); } template void intRealRealRealGSL(stack *s) { double x=pop(s); double n=pop(s); double a=pop(s); s->push(func(a,n,x)); checkGSLerror(); } template void realRealRealRealGSL(stack *s) { double x=pop(s); double n=pop(s); double a=pop(s); s->push(func(a,n,x)); checkGSLerror(); } template void realRealIntGSL(stack *s) { Int n=pop(s); double x=pop(s); s->push(func(x,unsignedcast(n))); checkGSLerror(); } // Add a GSL special function from the GNU GSL library template void addGSLRealFunc(symbol name, symbol arg1=SYM(x)) { addFunc(GSLModule->e.ve, realRealGSL, primReal(), name, formal(primReal(),arg1)); } // Add a GSL_PREC_DOUBLE GSL special function. template void addGSLDOUBLEFunc(symbol name, symbol arg1=SYM(x)) { addFunc(GSLModule->e.ve, realRealDOUBLE, primReal(), name, formal(primReal(),arg1)); } template void addGSLDOUBLE2Func(symbol name, symbol arg1=SYM(phi), symbol arg2=SYM(k)) { addFunc(GSLModule->e.ve, realRealRealDOUBLE, primReal(), name, formal(primReal(),arg1), formal(primReal(),arg2)); } template void realRealRealRealDOUBLE(stack *s) { double z=pop(s); double y=pop(s); double x=pop(s); s->push(func(x,y,z,GSL_PREC_DOUBLE)); checkGSLerror(); } template void addGSLDOUBLE3Func(symbol name, symbol arg1, symbol arg2, symbol arg3) { addFunc(GSLModule->e.ve, realRealRealRealDOUBLE, primReal(), name, formal(primReal(),arg1), formal(primReal(),arg2), formal(primReal(), arg3)); } template void realRealRealRealRealDOUBLE(stack *s) { double z=pop(s); double y=pop(s); double x=pop(s); double w=pop(s); s->push(func(w,x,y,z,GSL_PREC_DOUBLE)); checkGSLerror(); } template void addGSLDOUBLE4Func(symbol name, symbol arg1, symbol arg2, symbol arg3, symbol arg4) { addFunc(GSLModule->e.ve, realRealRealRealRealDOUBLE, primReal(), name, formal(primReal(),arg1), formal(primReal(),arg2), formal(primReal(), arg3), formal(primReal(), arg4)); } template void addGSLIntFunc(symbol name) { addFunc(GSLModule->e.ve, realIntGSL, primReal(), name, formal(primInt(),SYM(s))); } template void realSignedGSL(stack *s) { Int a = pop(s); s->push(func(intcast(a))); checkGSLerror(); } template void addGSLSignedFunc(symbol name, symbol arg1) { addFunc(GSLModule->e.ve, realSignedGSL, primReal(), name, formal(primInt(),arg1)); } template void addGSLIntRealFunc(symbol name, symbol arg1=SYM(n), symbol arg2=SYM(x)) { addFunc(GSLModule->e.ve, realIntRealGSL, primReal(), name, formal(primInt(),arg1), formal(primReal(),arg2)); } template void addGSLRealRealFunc(symbol name, symbol arg1=SYM(nu), symbol arg2=SYM(x)) { addFunc(GSLModule->e.ve, realRealRealGSL, primReal(), name, formal(primReal(),arg1), formal(primReal(),arg2)); } template void addGSLRealRealRealFunc(symbol name, symbol arg1, symbol arg2, symbol arg3) { addFunc(GSLModule->e.ve, realRealRealRealGSL, primReal(), name, formal(primReal(),arg1), formal(primReal(),arg2), formal(primReal(), arg3)); } template void addGSLRealRealRealFuncInt(symbol name, symbol arg1, symbol arg2, symbol arg3) { addFunc(GSLModule->e.ve, intRealRealRealGSL, primInt(), name, formal(primReal(),arg1), formal(primReal(),arg2), formal(primReal(), arg3)); } template void addGSLRealIntFunc(symbol name, symbol arg1=SYM(nu), symbol arg2=SYM(s)) { addFunc(GSLModule->e.ve, realRealIntGSL, primReal(), name, formal(primReal(),arg1), formal(primInt(),arg2)); } template void realRealSignedGSL(stack *s) { Int b = pop(s); double a = pop(s); s->push(func(a, intcast(b))); checkGSLerror(); } template void addGSLRealSignedFunc(symbol name, symbol arg1, symbol arg2) { addFunc(GSLModule->e.ve, realRealSignedGSL, primReal(), name, formal(primReal(),arg1), formal(primInt(),arg2)); } template void realUnsignedUnsignedGSL(stack *s) { Int b = pop(s); Int a = pop(s); s->push(func(unsignedcast(a), unsignedcast(b))); checkGSLerror(); } template void addGSLUnsignedUnsignedFunc(symbol name, symbol arg1, symbol arg2) { addFunc(GSLModule->e.ve, realUnsignedUnsignedGSL, primReal(), name, formal(primInt(), arg1), formal(primInt(), arg2)); } template void realIntRealRealGSL(stack *s) { double c = pop(s); double b = pop(s); Int a = pop(s); s->push(func(intcast(a), b, c)); checkGSLerror(); } template void addGSLIntRealRealFunc(symbol name, symbol arg1, symbol arg2, symbol arg3) { addFunc(GSLModule->e.ve, realIntRealRealGSL, primReal(), name, formal(primInt(), arg1), formal(primReal(), arg2), formal(primReal(), arg3)); } template void realIntIntRealGSL(stack *s) { double c = pop(s); Int b = pop(s); Int a = pop(s); s->push(func(intcast(a), intcast(b), c)); checkGSLerror(); } template void addGSLIntIntRealFunc(symbol name, symbol arg1, symbol arg2, symbol arg3) { addFunc(GSLModule->e.ve, realIntIntRealGSL, primReal(), name, formal(primInt(), arg1), formal(primInt(), arg2), formal(primReal(), arg3)); } template void realIntIntRealRealGSL(stack *s) { double d = pop(s); double c = pop(s); Int b = pop(s); Int a = pop(s); s->push(func(intcast(a), intcast(b), c, d)); checkGSLerror(); } template void addGSLIntIntRealRealFunc(symbol name, symbol arg1, symbol arg2, symbol arg3, symbol arg4) { addFunc(GSLModule->e.ve, realIntIntRealRealGSL, primReal(), name, formal(primInt(), arg1), formal(primInt(), arg2), formal(primReal(), arg3), formal(primReal(), arg4)); } template void realRealRealRealRealGSL(stack *s) { double d = pop(s); double c = pop(s); double b = pop(s); double a = pop(s); s->push(func(a, b, c, d)); checkGSLerror(); } template void addGSLRealRealRealRealFunc(symbol name, symbol arg1, symbol arg2, symbol arg3, symbol arg4) { addFunc(GSLModule->e.ve, realRealRealRealRealGSL, primReal(), name, formal(primReal(), arg1), formal(primReal(), arg2), formal(primReal(), arg3), formal(primReal(), arg4)); } template void realIntIntIntIntIntIntGSL(stack *s) { Int f = pop(s); Int e = pop(s); Int d = pop(s); Int c = pop(s); Int b = pop(s); Int a = pop(s); s->push(func(intcast(a), intcast(b), intcast(c), intcast(d), intcast(e), intcast(f))); checkGSLerror(); } template void addGSLIntIntIntIntIntIntFunc(symbol name, symbol arg1, symbol arg2, symbol arg3, symbol arg4, symbol arg5, symbol arg6) { addFunc(GSLModule->e.ve, realIntIntIntIntIntIntGSL, primReal(), name, formal(primInt(), arg1), formal(primInt(), arg2), formal(primInt(), arg3), formal(primInt(), arg4), formal(primInt(), arg5), formal(primInt(), arg6)); } template void realIntIntIntIntIntIntIntIntIntGSL(stack *s) { Int i = pop(s); Int h = pop(s); Int g = pop(s); Int f = pop(s); Int e = pop(s); Int d = pop(s); Int c = pop(s); Int b = pop(s); Int a = pop(s); s->push(func(intcast(a), intcast(b), intcast(c), intcast(d), intcast(e), intcast(f), intcast(g), intcast(h), intcast(i))); checkGSLerror(); } template void addGSLIntIntIntIntIntIntIntIntIntFunc(symbol name, symbol arg1, symbol arg2, symbol arg3, symbol arg4, symbol arg5, symbol arg6, symbol arg7, symbol arg8, symbol arg9) { addFunc(GSLModule->e.ve, realIntIntIntIntIntIntIntIntIntGSL, primReal(), name, formal(primInt(), arg1), formal(primInt(), arg2), formal(primInt(), arg3), formal(primInt(), arg4), formal(primInt(), arg5), formal(primInt(), arg6), formal(primInt(), arg7), formal(primInt(), arg8), formal(primInt(), arg9)); } template void realUIntRealGSL(stack *s) { double a = pop(s); unsigned int k = unsignedcast(pop(s)); s->push(func(k,a)); checkGSLerror(); } template void addGSLUIntRealFunc(symbol name, symbol arg1, symbol arg2) { addFunc(GSLModule->e.ve, realUIntRealGSL, primReal(), name, formal(primInt(), arg1), formal(primReal(), arg2)); } template void realUIntRealUIntGSL(stack *s) { unsigned int n = unsignedcast(pop(s)); double a = pop(s); unsigned int k = unsignedcast(pop(s)); s->push(func(k,a,n)); checkGSLerror(); } template void addGSLUIntRealUIntFunc(symbol name, symbol arg1, symbol arg2, symbol arg3) { addFunc(GSLModule->e.ve, realUIntRealUIntGSL, primReal(), name, formal(primInt(), arg1), formal(primReal(), arg2), formal(primInt(), arg3)); } template void realUIntRealRealGSL(stack *s) { double b = pop(s); double a = pop(s); unsigned int k = unsignedcast(pop(s)); s->push(func(k,a,b)); checkGSLerror(); } template void addGSLUIntRealRealFunc(symbol name, symbol arg1, symbol arg2, symbol arg3) { addFunc(GSLModule->e.ve, realUIntRealRealGSL, primReal(), name, formal(primInt(), arg1), formal(primReal(), arg2), formal(primReal(), arg3)); } template void realUIntUIntUIntUIntGSL(stack *s) { unsigned int t = unsignedcast(pop(s)); unsigned int n2 = unsignedcast(pop(s)); unsigned int n1 = unsignedcast(pop(s)); unsigned int k = unsignedcast(pop(s)); s->push(func(k,n1,n2,t)); checkGSLerror(); } template void addGSLUIntUIntUIntUIntFunc(symbol name, symbol arg1, symbol arg2, symbol arg3, symbol arg4) { addFunc(GSLModule->e.ve, realUIntUIntUIntUIntGSL, primReal(), name, formal(primInt(), arg1), formal(primInt(), arg2), formal(primInt(), arg3), formal(primInt(), arg4)); } // GSL random number generators gsl_rng *GSLrng=0; const gsl_rng_type **GSLrngFirstType=gsl_rng_types_setup(); inline void checkGSLrng() { if(GSLrng == 0) error(GSLrngnull); } void GSLrngFree() { if(GSLrng != 0) gsl_rng_free(GSLrng); GSLrng=0; } void GSLrngInit(stack *s) { string n = pop(s,string()); const gsl_rng_type **t; if(n.empty()) t = &gsl_rng_default; else { for(t=GSLrngFirstType; *t!=0; ++t) if(n == string((*t)->name)) break; if(*t == 0) error(GSLinvalid); } GSLrngFree(); GSLrng = gsl_rng_alloc(*t); if(GSLrng == 0) { GSLerror=false; error("insufficient memory for allocation of GSL random number generator"); } } void GSLrngList(stack *s) { array* a = new array(0); const gsl_rng_type **t; for(t=GSLrngFirstType; *t!=0; ++t) { a->push(string((*t)->name)); } s->push(a); checkGSLerror(); } void GSLrngSet(stack *s) { Int i=pop(s,-1); checkGSLrng(); if(i < 0) gsl_rng_set(GSLrng,gsl_rng_default_seed); else gsl_rng_set(GSLrng,unsignedcast(i)); checkGSLerror(); } template void intVoidGSLrng(stack *s) { s->push(func(GSLrng)); checkGSLrng(); checkGSLerror(); } template void addGSLrngVoidFuncInt(symbol name) { addFunc(GSLModule->e.ve, intVoidGSLrng, primInt(), name); } template void intULongGSLrng(stack *s) { unsigned long int i = unsignedcast(pop(s)); checkGSLrng(); s->push(func(GSLrng,i)); checkGSLerror(); } template void addGSLrngULongFuncInt(symbol name, symbol arg1) { addFunc(GSLModule->e.ve, intULongGSLrng, primInt(), name, formal(primInt(), arg1)); } template void intRealGSLrng(stack *s) { double x = pop(s); checkGSLrng(); s->push(func(GSLrng,x)); checkGSLerror(); } template void addGSLrngRealFuncInt(symbol name, symbol arg1) { addFunc(GSLModule->e.ve, intRealGSLrng, primInt(), name, formal(primReal(), arg1)); } template void intRealRealGSLrng(stack *s) { double y = pop(s); double x = pop(s); checkGSLrng(); s->push(func(GSLrng,x,y)); checkGSLerror(); } template void addGSLrngRealRealFuncInt(symbol name, symbol arg1, symbol arg2) { addFunc(GSLModule->e.ve, intRealRealGSLrng, primInt(), name, formal(primReal(), arg1), formal(primReal(), arg2)); } template void realVoidGSLrng(stack *s) { checkGSLrng(); s->push(func(GSLrng)); checkGSLerror(); } template void addGSLrngVoidFunc(symbol name) { addFunc(GSLModule->e.ve, realVoidGSLrng, primReal(), name); } template void realRealGSLrng(stack *s) { double x = pop(s); checkGSLrng(); s->push(func(GSLrng,x)); checkGSLerror(); } template void addGSLrngRealFunc(symbol name, symbol arg1) { addFunc(GSLModule->e.ve, realRealGSLrng, primReal(), name, formal(primReal(), arg1)); } template void realRealRealGSLrng(stack *s) { double b = pop(s); double a = pop(s); checkGSLrng(); s->push(func(GSLrng,a,b)); checkGSLerror(); } template void addGSLrngRealRealFunc(symbol name, symbol arg1, symbol arg2) { addFunc(GSLModule->e.ve, realRealRealGSLrng, primReal(), name, formal(primReal(), arg1), formal(primReal(), arg2)); } template void intRealUIntGSLrng(stack *s) { unsigned int n = unsignedcast(pop(s)); double a = pop(s); checkGSLrng(); s->push(func(GSLrng,a,n)); checkGSLerror(); } template void addGSLrngRealUIntFuncInt(symbol name, symbol arg1, symbol arg2) { addFunc(GSLModule->e.ve, intRealUIntGSLrng, primInt(), name, formal(primReal(), arg1), formal(primInt(), arg2)); } template void intUIntUIntUIntGSLrng(stack *s) { unsigned int t = unsignedcast(pop(s)); unsigned int n2 = unsignedcast(pop(s)); unsigned int n1 = unsignedcast(pop(s)); checkGSLrng(); s->push(func(GSLrng,n1,n2,t)); checkGSLerror(); } template void addGSLrngUIntUIntUIntFuncInt(symbol name, symbol arg1, symbol arg2, symbol arg3) { addFunc(GSLModule->e.ve, intUIntUIntUIntGSLrng, primInt(), name, formal(primInt(), arg1), formal(primInt(), arg2), formal(primInt(), arg3)); } template void stringVoidGSLrng(stack *s) { checkGSLrng(); s->push(func(GSLrng)); checkGSLerror(); } template void addGSLrngVoidFuncString(symbol name) { addFunc(GSLModule->e.ve, stringVoidGSLrng, primString(), name); } void GSLrng_gaussian(stack *s) { string method = pop(s,string("polar")); double sigma = pop(s,1.0); double mu = pop(s,0.0); checkGSLrng(); double x=mu; if(method == "polar") x += gsl_ran_gaussian(GSLrng,sigma); else if(method == "ziggurat") x += gsl_ran_gaussian_ziggurat(GSLrng,sigma); else if(method == "ratio") x += gsl_ran_gaussian_ratio_method(GSLrng,sigma); else error(GSLinvalid); s->push(x); checkGSLerror(); } template void realRealRealRealGSLgaussian(stack *s) { double sigma = pop(s,1.0); double mu = pop(s,0.0); double x = pop(s); s->push(func(x-mu,sigma)); checkGSLerror(); } template void addGSLgaussianrealRealRealRealFunc(symbol name, symbol arg1) { addFunc(GSLModule->e.ve, realRealRealRealGSLgaussian, primReal(), name, formal(primReal(), arg1), formal(primReal(), SYM(mu), true, false), formal(primReal(), SYM(sigma), true, false)); } template void realRealRealRealGSLinvgaussian(stack *s) { double sigma = pop(s,1.0); double mu = pop(s,0.0); double x = pop(s); s->push(func(x,sigma)+mu); checkGSLerror(); } template void addGSLinvgaussianrealRealRealRealFunc(symbol name, symbol arg1) { addFunc(GSLModule->e.ve, realRealRealRealGSLinvgaussian, primReal(), name, formal(primReal(), arg1), formal(primReal(), SYM(mu), true, false), formal(primReal(), SYM(sigma), true, false)); } void GSLrng_bivariate_gaussian(stack *s) { double rho = pop(s,0.0); pair sigma = pop(s,pair(1.0,1.0)); pair mu = pop(s,pair(0.0,0.0)); checkGSLrng(); double x,y; gsl_ran_bivariate_gaussian(GSLrng,sigma.getx(),sigma.gety(),rho,&x,&y); s->push(pair(x,y)+mu); checkGSLerror(); } void GSLpdf_bivariate_gaussian(stack *s) { double rho = pop(s,0.0); pair sigma = pop(s,pair(1.0,1.0)); pair mu = pop(s,pair(0.0,0.0)); pair z = pop(s); s->push(gsl_ran_bivariate_gaussian_pdf(z.getx()+mu.getx(),z.gety()+mu.gety(), sigma.getx(),sigma.gety(),rho)); checkGSLerror(); } void GSLrng_levy(stack *s) { double beta = pop(s,0.0); double alpha = pop(s); double c = pop(s); if((alpha<=0) || (alpha>2)) error(GSLinvalid); if((beta<-1) || (beta>1)) error(GSLinvalid); checkGSLrng(); double x; if(beta==0) x=gsl_ran_levy(GSLrng,c,alpha); else x=gsl_ran_levy_skew(GSLrng,c,alpha,beta); s->push(x); checkGSLerror(); } void GSLrng_gamma(stack *s) { string method = pop(s,string("mt")); double b = pop(s); double a = pop(s); checkGSLrng(); double x=0.0; if(method == "mt") x = gsl_ran_gamma(GSLrng,a,b); else if(method == "knuth") x = gsl_ran_gamma_knuth(GSLrng,a,b); else error(GSLinvalid); s->push(x); checkGSLerror(); } void GSLrng_dir2d(stack *s) { string method = pop(s,string("neumann")); checkGSLrng(); double x=0, y=0; if(method == "neumann") gsl_ran_dir_2d(GSLrng,&x,&y); else if(method == "trig") gsl_ran_dir_2d_trig_method(GSLrng,&x,&y); else error(GSLinvalid); s->push(pair(x,y)); checkGSLerror(); } void GSLrng_dir3d(stack *s) { checkGSLrng(); double x,y,z; gsl_ran_dir_3d(GSLrng,&x,&y,&z); s->push(triple(x,y,z)); checkGSLerror(); } void GSLrng_dir(stack *s) { size_t n = (size_t) unsignedcast(pop(s)); if(n==0) error(GSLinvalid); checkGSLrng(); double* p = new double[n]; gsl_ran_dir_nd(GSLrng,n,p); s->push(copyCArray(n,p)); delete[] p; checkGSLerror(); } void GSLrng_dirichlet(stack *s) { array* alpha = pop(s); size_t K = checkArray(alpha); checkGSLrng(); double* calpha; copyArrayC(calpha,alpha); double* ctheta = new double[K]; gsl_ran_dirichlet(GSLrng,K,calpha,ctheta); s->push(copyCArray(K,ctheta)); delete[] ctheta; delete[] calpha; checkGSLerror(); } void GSLpdf_dirichlet(stack *s) { array* theta = pop(s); array* alpha = pop(s); size_t K = checkArray(alpha); if(checkArray(theta) != K) error(GSLinvalid); double* calpha; copyArrayC(calpha,alpha); double* ctheta; copyArrayC(ctheta,theta); s->push(gsl_ran_dirichlet_pdf(K,calpha,ctheta)); delete[] ctheta; delete[] calpha; checkGSLerror(); } void GSLrng_multinomial(stack *s) { array* p = pop(s); unsigned int N = unsignedcast(pop(s)); size_t K = checkArray(p); checkGSLrng(); double* cp; copyArrayC(cp,p); unsigned int* cn = new unsigned int[K]; gsl_ran_multinomial(GSLrng,K,N,cp,cn); s->push(copyCArray(K,cn)); delete[] cn; delete[] cp; checkGSLerror(); } void GSLpdf_multinomial(stack *s) { array* n = pop(s); array* p = pop(s); size_t K = checkArray(p); if(K != checkArray(n)) error(GSLinvalid); double* cp; copyArrayC(cp,p); unsigned int* cn; copyArrayC(cn,n,unsignedcast); s->push(gsl_ran_multinomial_pdf(K,cp,cn)); delete[] cn; delete[] cp; checkGSLerror(); } void GSLsf_elljac_e(stack *s) { double m = pop(s); double u = pop(s); double sn,cn,dn; gsl_sf_elljac_e(u,m,&sn,&cn,&dn); array *result=new array(3); (*result)[0]=sn; (*result)[1]=cn; (*result)[2]=dn; s->push(result); } // Handle GSL errors gracefully. void GSLerrorhandler(const char *reason, const char *, int, int) { if(!GSLerror) { vm::errornothrow(reason); GSLerror=true; } } void gen_rungsl_venv(venv &ve) { GSLModule=new types::dummyRecord(SYM(gsl)); gsl_set_error_handler(GSLerrorhandler); // Common functions addGSLRealRealFunc(SYM(hypot),SYM(x),SYM(y)); // addGSLRealRealRealFunc(SYM(hypot),SYM(x),SYM(y),SYM(z)); addGSLRealRealRealFuncInt(SYM(fcmp),SYM(x),SYM(y),SYM(epsilon)); // Airy functions addGSLDOUBLEFunc(SYM(Ai)); addGSLDOUBLEFunc(SYM(Bi)); addGSLDOUBLEFunc(SYM(Ai_scaled)); addGSLDOUBLEFunc(SYM(Bi_scaled)); addGSLDOUBLEFunc(SYM(Ai_deriv)); addGSLDOUBLEFunc(SYM(Bi_deriv)); addGSLDOUBLEFunc(SYM(Ai_deriv_scaled)); addGSLDOUBLEFunc(SYM(Bi_deriv_scaled)); addGSLIntFunc(SYM(zero_Ai)); addGSLIntFunc(SYM(zero_Bi)); addGSLIntFunc(SYM(zero_Ai_deriv)); addGSLIntFunc(SYM(zero_Bi_deriv)); // Bessel functions addGSLRealFunc(SYM(J0)); addGSLRealFunc(SYM(J1)); addGSLIntRealFunc(SYM(Jn)); addGSLRealFunc(SYM(Y0)); addGSLRealFunc(SYM(Y1)); addGSLIntRealFunc(SYM(Yn)); addGSLRealFunc(SYM(I0)); addGSLRealFunc(SYM(I1)); addGSLIntRealFunc(SYM(I)); addGSLRealFunc(SYM(I0_scaled)); addGSLRealFunc(SYM(I1_scaled)); addGSLIntRealFunc(SYM(I_scaled)); addGSLRealFunc(SYM(K0)); addGSLRealFunc(SYM(K1)); addGSLIntRealFunc(SYM(K)); addGSLRealFunc(SYM(K0_scaled)); addGSLRealFunc(SYM(K1_scaled)); addGSLIntRealFunc(SYM(K_scaled)); addGSLRealFunc(SYM(j0)); addGSLRealFunc(SYM(j1)); addGSLRealFunc(SYM(j2)); addGSLIntRealFunc(SYM(j),SYM(l)); addGSLRealFunc(SYM(y0)); addGSLRealFunc(SYM(y1)); addGSLRealFunc(SYM(y2)); addGSLIntRealFunc(SYM(y),SYM(l)); addGSLRealFunc(SYM(i0_scaled)); addGSLRealFunc(SYM(i1_scaled)); addGSLRealFunc(SYM(i2_scaled)); addGSLIntRealFunc(SYM(i_scaled),SYM(l)); addGSLRealFunc(SYM(k0_scaled)); addGSLRealFunc(SYM(k1_scaled)); addGSLRealFunc(SYM(k2_scaled)); addGSLIntRealFunc(SYM(k_scaled),SYM(l)); addGSLRealRealFunc(SYM(J)); addGSLRealRealFunc(SYM(Y)); addGSLRealRealFunc(SYM(I)); addGSLRealRealFunc(SYM(I_scaled)); addGSLRealRealFunc(SYM(K)); addGSLRealRealFunc(SYM(lnK)); addGSLRealRealFunc(SYM(K_scaled)); addGSLIntFunc(SYM(zero_J0)); addGSLIntFunc(SYM(zero_J1)); addGSLRealIntFunc(SYM(zero_J)); // Clausen functions addGSLRealFunc(SYM(clausen)); // Coulomb functions addGSLRealRealFunc(SYM(hydrogenicR_1),SYM(Z),SYM(r)); addGSLIntIntRealRealFunc(SYM(hydrogenicR),SYM(n),SYM(l), SYM(Z),SYM(r)); // Missing: F_L(eta,x), G_L(eta,x), C_L(eta) // Coupling coefficients addGSLIntIntIntIntIntIntFunc(SYM(coupling_3j),SYM(two_ja), SYM(two_jb),SYM(two_jc), SYM(two_ma), SYM(two_mb),SYM(two_mc)); addGSLIntIntIntIntIntIntFunc(SYM(coupling_6j),SYM(two_ja), SYM(two_jb),SYM(two_jc), SYM(two_jd), SYM(two_je),SYM(two_jf)); addGSLIntIntIntIntIntIntIntIntIntFunc(SYM(coupling_9j), SYM(two_ja), SYM(two_jb), SYM(two_jc), SYM(two_jd), SYM(two_je), SYM(two_jf), SYM(two_jg), SYM(two_jh), SYM(two_ji)); // Dawson function addGSLRealFunc(SYM(dawson)); // Debye functions addGSLRealFunc(SYM(debye_1)); addGSLRealFunc(SYM(debye_2)); addGSLRealFunc(SYM(debye_3)); addGSLRealFunc(SYM(debye_4)); addGSLRealFunc(SYM(debye_5)); addGSLRealFunc(SYM(debye_6)); // Dilogarithm addGSLRealFunc(SYM(dilog)); // Missing: complex dilogarithm // Elementary operations // we don't support errors at the moment // Elliptic integrals addGSLDOUBLEFunc(SYM(K),SYM(k)); addGSLDOUBLEFunc(SYM(E),SYM(k)); addGSLDOUBLE2Func(SYM(P),SYM(k),SYM(n)); addGSLDOUBLE2Func(SYM(F)); addGSLDOUBLE2Func(SYM(E)); addGSLDOUBLE3Func(SYM(P),SYM(phi),SYM(k),SYM(n)); #if GSL_MAJOR_VERSION >= 2 addGSLDOUBLE2Func(SYM(D),SYM(phi),SYM(k)); #else addGSLDOUBLE3Func(SYM(D),SYM(phi),SYM(k),SYM(n)); #endif addGSLDOUBLE2Func(SYM(RC),SYM(x),SYM(y)); addGSLDOUBLE3Func(SYM(RD),SYM(x),SYM(y),SYM(z)); addGSLDOUBLE3Func(SYM(RF),SYM(x),SYM(y),SYM(z)); addGSLDOUBLE4Func(SYM(RJ),SYM(x),SYM(y),SYM(z),SYM(p)); // Error functions addGSLRealFunc(SYM(erf)); addGSLRealFunc(SYM(erfc)); addGSLRealFunc(SYM(log_erfc)); addGSLRealFunc(SYM(erf_Z)); addGSLRealFunc(SYM(erf_Q)); addGSLRealFunc(SYM(hazard)); // Exponential functions addGSLRealRealFunc(SYM(exp_mult),SYM(x),SYM(y)); // addGSLRealFunc(SYM(expm1)); addGSLRealFunc(SYM(exprel)); addGSLRealFunc(SYM(exprel_2)); addGSLIntRealFunc(SYM(exprel),SYM(n),SYM(x)); // Exponential integrals addGSLRealFunc(SYM(E1)); addGSLRealFunc(SYM(E2)); // addGSLIntRealFunc(SYM(En),SYM(n),SYM(x)); addGSLRealFunc(SYM(Ei)); addGSLRealFunc(SYM(Shi)); addGSLRealFunc(SYM(Chi)); addGSLRealFunc(SYM(Ei3)); addGSLRealFunc(SYM(Si)); addGSLRealFunc(SYM(Ci)); addGSLRealFunc(SYM(atanint)); // Fermi--Dirac function addGSLRealFunc(SYM(FermiDiracM1)); addGSLRealFunc(SYM(FermiDirac0)); addGSLRealFunc(SYM(FermiDirac1)); addGSLRealFunc(SYM(FermiDirac2)); addGSLIntRealFunc(SYM(FermiDirac),SYM(j),SYM(x)); addGSLRealFunc(SYM(FermiDiracMHalf)); addGSLRealFunc(SYM(FermiDiracHalf)); addGSLRealFunc(SYM(FermiDirac3Half)); addGSLRealRealFunc(SYM(FermiDiracInc0),SYM(x), SYM(b)); // Gamma and beta functions addGSLRealFunc(SYM(gamma)); addGSLRealFunc(SYM(lngamma)); addGSLRealFunc(SYM(gammastar)); addGSLRealFunc(SYM(gammainv)); addGSLIntFunc(SYM(fact)); addGSLIntFunc(SYM(doublefact)); addGSLIntFunc(SYM(lnfact)); addGSLIntFunc(SYM(lndoublefact)); addGSLUnsignedUnsignedFunc(SYM(choose),SYM(n),SYM(m)); addGSLUnsignedUnsignedFunc(SYM(lnchoose),SYM(n),SYM(m)); addGSLIntRealFunc(SYM(taylorcoeff),SYM(n),SYM(x)); addGSLRealRealFunc(SYM(poch),SYM(a),SYM(x)); addGSLRealRealFunc(SYM(lnpoch),SYM(a),SYM(x)); addGSLRealRealFunc(SYM(pochrel),SYM(a),SYM(x)); addGSLRealRealFunc(SYM(gamma),SYM(a),SYM(x)); addGSLRealRealFunc(SYM(gamma_Q),SYM(a),SYM(x)); addGSLRealRealFunc(SYM(gamma_P),SYM(a),SYM(x)); addGSLRealRealFunc(SYM(beta),SYM(a),SYM(b)); addGSLRealRealFunc(SYM(lnbeta),SYM(a),SYM(b)); addGSLRealRealRealFunc(SYM(beta),SYM(a),SYM(b),SYM(x)); // Gegenbauer functions addGSLRealRealFunc(SYM(gegenpoly_1),SYM(lambda),SYM(x)); addGSLRealRealFunc(SYM(gegenpoly_2),SYM(lambda),SYM(x)); addGSLRealRealFunc(SYM(gegenpoly_3),SYM(lambda),SYM(x)); addGSLIntRealRealFunc(SYM(gegenpoly),SYM(n),SYM(lambda), SYM(x)); // Hypergeometric functions addGSLRealRealFunc(SYM(hy0F1),SYM(c),SYM(x)); addGSLIntIntRealFunc(SYM(hy1F1),SYM(m),SYM(n),SYM(x)); addGSLRealRealRealFunc(SYM(hy1F1),SYM(a),SYM(b),SYM(x)); addGSLIntIntRealFunc(SYM(U),SYM(m),SYM(n),SYM(x)); addGSLRealRealRealFunc(SYM(U),SYM(a),SYM(b),SYM(x)); addGSLRealRealRealRealFunc(SYM(hy2F1),SYM(a),SYM(b),SYM(c), SYM(x)); addGSLRealRealRealRealFunc(SYM(hy2F1_conj),SYM(aR), SYM(aI),SYM(c),SYM(x)); addGSLRealRealRealRealFunc(SYM(hy2F1_renorm),SYM(a), SYM(b),SYM(c),SYM(x)); addGSLRealRealRealRealFunc (SYM(hy2F1_conj_renorm),SYM(aR),SYM(aI),SYM(c),SYM(x)); addGSLRealRealRealFunc(SYM(hy2F0),SYM(a),SYM(b),SYM(x)); // Laguerre functions addGSLRealRealFunc(SYM(L1),SYM(a),SYM(x)); addGSLRealRealFunc(SYM(L2),SYM(a),SYM(x)); addGSLRealRealFunc(SYM(L3),SYM(a),SYM(x)); addGSLIntRealRealFunc(SYM(L),SYM(n),SYM(a),SYM(x)); // Lambert W functions addGSLRealFunc(SYM(W0)); addGSLRealFunc(SYM(Wm1)); // Legendre functions and spherical harmonics addGSLRealFunc(SYM(P1)); addGSLRealFunc(SYM(P2)); addGSLRealFunc(SYM(P3)); addGSLIntRealFunc(SYM(Pl),SYM(l)); addGSLRealFunc(SYM(Q0)); addGSLRealFunc(SYM(Q1)); addGSLIntRealFunc(SYM(Ql),SYM(l)); addGSLIntIntRealFunc(SYM(Plm),SYM(l),SYM(m),SYM(x)); addGSLIntIntRealFunc(SYM(sphPlm),SYM(l),SYM(m), SYM(x)); addGSLRealRealFunc(SYM(conicalP_half),SYM(lambda), SYM(x)); addGSLRealRealFunc(SYM(conicalP_mhalf),SYM(lambda), SYM(x)); addGSLRealRealFunc(SYM(conicalP_0),SYM(lambda),SYM(x)); addGSLRealRealFunc(SYM(conicalP_1),SYM(lambda),SYM(x)); addGSLIntRealRealFunc(SYM(conicalP_sph_reg),SYM(l), SYM(lambda),SYM(x)); addGSLIntRealRealFunc(SYM(conicalP_cyl_reg),SYM(m), SYM(lambda),SYM(x)); addGSLRealRealFunc(SYM(H3d0),SYM(lambda),SYM(eta)); addGSLRealRealFunc(SYM(H3d1),SYM(lambda),SYM(eta)); addGSLIntRealRealFunc(SYM(H3d),SYM(l),SYM(lambda), SYM(eta)); // Logarithm and related functions addGSLRealFunc(SYM(logabs)); // addGSLRealFunc(SYM(log1p)); addGSLRealFunc(SYM(log1pm)); // Matthieu functions // to be implemented // Power function addGSLRealSignedFunc(SYM(pow),SYM(x),SYM(n)); // Psi (digamma) function addGSLSignedFunc(SYM(psi),SYM(n)); addGSLRealFunc(SYM(psi)); addGSLRealFunc(SYM(psi_1piy),SYM(y)); addGSLSignedFunc(SYM(psi1),SYM(n)); addGSLRealFunc(SYM(psi1),SYM(x)); addGSLIntRealFunc(SYM(psi),SYM(n),SYM(x)); // Synchrotron functions addGSLRealFunc(SYM(synchrotron_1)); addGSLRealFunc(SYM(synchrotron_2)); // Transport functions addGSLRealFunc(SYM(transport_2)); addGSLRealFunc(SYM(transport_3)); addGSLRealFunc(SYM(transport_4)); addGSLRealFunc(SYM(transport_5)); // Trigonometric functions addGSLRealFunc(SYM(sinc)); addGSLRealFunc(SYM(lnsinh)); addGSLRealFunc(SYM(lncosh)); // Zeta functions addGSLSignedFunc(SYM(zeta),SYM(n)); addGSLRealFunc(SYM(zeta),SYM(s)); addGSLSignedFunc(SYM(zetam1),SYM(n)); addGSLRealFunc(SYM(zetam1),SYM(s)); addGSLRealRealFunc(SYM(hzeta),SYM(s),SYM(q)); addGSLSignedFunc(SYM(eta),SYM(n)); addGSLRealFunc(SYM(eta),SYM(s)); // Random number generation gsl_rng_env_setup(); addFunc(GSLModule->e.ve,GSLrngInit,primVoid(),SYM(rng_init), formal(primString(),SYM(name),true,false)); addFunc(GSLModule->e.ve,GSLrngList,stringArray(),SYM(rng_list)); addFunc(GSLModule->e.ve,GSLrngSet,primVoid(),SYM(rng_set), formal(primInt(),SYM(seed),true,false)); addGSLrngVoidFuncString(SYM(rng_name)); addGSLrngVoidFuncInt(SYM(rng_min)); addGSLrngVoidFuncInt(SYM(rng_max)); addGSLrngVoidFuncInt(SYM(rng_get)); addGSLrngULongFuncInt(SYM(rng_uniform_int),SYM(n)); addGSLrngVoidFunc(SYM(rng_uniform)); addGSLrngVoidFunc(SYM(rng_uniform_pos)); // Gaussian distribution addFunc(GSLModule->e.ve,GSLrng_gaussian,primReal(),SYM(rng_gaussian), formal(primReal(),SYM(mu),true,false), formal(primReal(),SYM(sigma),true,false), formal(primString(),SYM(method),true,false)); addGSLgaussianrealRealRealRealFunc(SYM(pdf_gaussian), SYM(x)); addGSLgaussianrealRealRealRealFunc(SYM(cdf_gaussian_P), SYM(x)); addGSLgaussianrealRealRealRealFunc(SYM(cdf_gaussian_Q), SYM(x)); addGSLinvgaussianrealRealRealRealFunc (SYM(cdf_gaussian_Pinv),SYM(x)); addGSLinvgaussianrealRealRealRealFunc (SYM(cdf_gaussian_Qinv),SYM(x)); // Gaussian tail distribution addGSLrngRealRealFunc(SYM(rng_gaussian_tail),SYM(a), SYM(sigma)); addGSLRealRealRealFunc(SYM(pdf_gaussian_tail), SYM(x),SYM(a),SYM(sigma)); // Bivariate Gaussian distribution addFunc(GSLModule->e.ve,GSLrng_bivariate_gaussian,primPair(), SYM(rng_bivariate_gaussian), formal(primPair(),SYM(mu),true,true), formal(primPair(),SYM(sigma),true,true), formal(primReal(),SYM(rho),true,false)); addFunc(GSLModule->e.ve,GSLpdf_bivariate_gaussian,primReal(), SYM(pdf_bivariate_gaussian), formal(primPair(),SYM(z),false,true), formal(primPair(),SYM(mu),true,true), formal(primPair(),SYM(sigma),true,true), formal(primReal(),SYM(rho),true,false)); #define addGSLrealdist1param(NAME,ARG) \ addGSLrngRealFunc \ (SYM(rng_##NAME),SYM(ARG)); \ addGSLRealRealFunc \ (SYM(pdf_##NAME),SYM(x),SYM(ARG)); \ addGSLRealRealFunc \ (SYM(cdf_##NAME##_P),SYM(x),SYM(ARG)); \ addGSLRealRealFunc \ (SYM(cdf_##NAME##_Q),SYM(x),SYM(ARG)); \ addGSLRealRealFunc \ (SYM(cdf_##NAME##_Pinv),SYM(P),SYM(ARG)); \ addGSLRealRealFunc \ (SYM(cdf_##NAME##_Qinv),SYM(Q),SYM(ARG)) // Exponential, Laplace, Cauchy, Rayleigh, Chi-squared, t, // and Logistic distribution addGSLrealdist1param(exponential,mu); addGSLrealdist1param(laplace,a); addGSLrealdist1param(cauchy,a); addGSLrealdist1param(rayleigh,mu); addGSLrealdist1param(chisq,mu); addGSLrealdist1param(tdist,mu); addGSLrealdist1param(logistic,mu); #undef addGSLrealdist1param #define addGSLrealdist2param(NAME,ARG1,ARG2) \ addGSLrngRealRealFunc \ (SYM(rng_##NAME),SYM(ARG1),SYM(ARG2)); \ addGSLRealRealRealFunc \ (SYM(pdf_##NAME),SYM(x),SYM(ARG1),SYM(ARG2)); \ addGSLRealRealRealFunc \ (SYM(cdf_##NAME##_P),SYM(x),SYM(ARG1),SYM(ARG2)); \ addGSLRealRealRealFunc \ (SYM(cdf_##NAME##_Q),SYM(x),SYM(ARG1),SYM(ARG2)); \ addGSLRealRealRealFunc \ (SYM(cdf_##NAME##_Pinv),SYM(P),SYM(ARG1),SYM(ARG2)); \ addGSLRealRealRealFunc \ (SYM(cdf_##NAME##_Qinv),SYM(Q),SYM(ARG1),SYM(ARG2)) // Uniform, log-normal, F, Beta, Pareto, Weibull, Type-1 Gumbel, // and Type-2 Gumbel distribution addGSLrealdist2param(flat,a,b); addGSLrealdist2param(lognormal,zeta,sigma); addGSLrealdist2param(fdist,nu1,nu2); addGSLrealdist2param(beta,a,b); addGSLrealdist2param(pareto,a,b); addGSLrealdist2param(weibull,a,b); addGSLrealdist2param(gumbel1,a,b); addGSLrealdist2param(gumbel2,a,b); #undef addGSLrealdist2param // Exponential power distribution addGSLrngRealRealFunc (SYM(rng_exppow),SYM(a),SYM(b)); addGSLRealRealRealFunc (SYM(pdf_exppow),SYM(x),SYM(a),SYM(b)); addGSLRealRealRealFunc (SYM(cdf_exppow_P),SYM(x),SYM(a),SYM(b)); addGSLRealRealRealFunc (SYM(cdf_exppow_Q),SYM(x),SYM(a),SYM(b)); // Exponential power distribution addGSLrngRealRealFunc (SYM(rng_rayleigh_tail),SYM(a),SYM(sigma)); addGSLRealRealRealFunc (SYM(pdf_rayleigh_tail),SYM(x),SYM(a),SYM(sigma)); // Landau distribution addGSLrngVoidFunc(SYM(rng_landau)); addGSLRealFunc(SYM(pdf_landau),SYM(x)); // Levy skwew alpha-stable distribution addFunc(GSLModule->e.ve,GSLrng_levy,primReal(),SYM(rng_levy), formal(primReal(),SYM(c)), formal(primReal(),SYM(alpha)), formal(primReal(),SYM(beta),true,false)); // Gamma distribution addFunc(GSLModule->e.ve,GSLrng_gamma,primReal(),SYM(rng_gamma), formal(primReal(),SYM(a)), formal(primReal(),SYM(b)), formal(primString(),SYM(method),true,false)); addGSLRealRealRealFunc (SYM(pdf_gamma),SYM(x),SYM(a),SYM(b)); addGSLRealRealRealFunc (SYM(cdf_gamma_P),SYM(x),SYM(a),SYM(b)); addGSLRealRealRealFunc (SYM(cdf_gamma_Q),SYM(x),SYM(a),SYM(b)); addGSLRealRealRealFunc (SYM(cdf_gamma_Pinv),SYM(P),SYM(a),SYM(b)); addGSLRealRealRealFunc (SYM(cdf_gamma_Qinv),SYM(Q),SYM(a),SYM(b)); // Sperical distributions addFunc(GSLModule->e.ve,GSLrng_dir2d,primPair(),SYM(rng_dir2d), formal(primString(),SYM(method),true,false)); addFunc(GSLModule->e.ve,GSLrng_dir3d,primTriple(),SYM(rng_dir3d)); addFunc(GSLModule->e.ve,GSLrng_dir,realArray(),SYM(rng_dir), formal(primInt(),SYM(n))); // Elliptic functions (Jacobi) addFunc(GSLModule->e.ve,GSLsf_elljac_e,realArray(),SYM(sncndn), formal(primReal(),SYM(u)),formal(primReal(),SYM(m))); // Dirirchlet distribution addFunc(GSLModule->e.ve,GSLrng_dirichlet,realArray(),SYM(rng_dirichlet), formal(realArray(),SYM(alpha))); addFunc(GSLModule->e.ve,GSLpdf_dirichlet,primReal(),SYM(pdf_dirichlet), formal(realArray(),SYM(alpha)), formal(realArray(),SYM(theta))); // General discrete distributions // to be implemented #define addGSLdiscdist1param(NAME,ARG,TYPE) \ addGSLrng##TYPE##FuncInt \ (SYM(rng_##NAME),SYM(ARG)); \ addGSLUInt##TYPE##Func \ (SYM(pdf_##NAME),SYM(k),SYM(ARG)); \ addGSLUInt##TYPE##Func \ (SYM(cdf_##NAME##_P),SYM(k),SYM(ARG)); \ addGSLUInt##TYPE##Func \ (SYM(cdf_##NAME##_Q),SYM(k),SYM(ARG)) // Poisson, geometric distributions addGSLdiscdist1param(poisson,mu,Real); addGSLdiscdist1param(geometric,p,Real); #undef addGSLdiscdist1param #define addGSLdiscdist2param(NAME,ARG1,TYPE1,ARG2,TYPE2) \ addGSLrng##TYPE1##TYPE2##FuncInt \ (SYM(rng_##NAME),SYM(ARG1),SYM(ARG2)); \ addGSLUInt##TYPE1##TYPE2##Func \ (SYM(pdf_##NAME),SYM(k),SYM(ARG1),SYM(ARG2)); \ addGSLUInt##TYPE1##TYPE2##Func \ (SYM(cdf_##NAME##_P),SYM(k),SYM(ARG1),SYM(ARG2)); \ addGSLUInt##TYPE1##TYPE2##Func \ (SYM(cdf_##NAME##_Q),SYM(k),SYM(ARG1),SYM(ARG2)) // Binomial, negative binomial distributions addGSLdiscdist2param(binomial,p,Real,n,UInt); addGSLdiscdist2param(negative_binomial,p,Real,n,Real); #undef addGSLdiscdist2param // Logarithmic distribution addGSLrngRealFuncInt(SYM(rng_logarithmic),SYM(p)); addGSLUIntRealFunc(SYM(pdf_logarithmic),SYM(k), SYM(p)); // Bernoulli distribution addGSLrngRealFuncInt(SYM(rng_bernoulli),SYM(p)); addGSLUIntRealFunc(SYM(pdf_bernoulli),SYM(k),SYM(p)); // Multinomial distribution addFunc(GSLModule->e.ve,GSLrng_multinomial,IntArray(),SYM(rng_multinomial), formal(primInt(),SYM(n)), formal(realArray(),SYM(p))); addFunc(GSLModule->e.ve,GSLpdf_multinomial,primReal(),SYM(pdf_multinomial), formal(realArray(),SYM(p)), formal(IntArray(),SYM(n))); // Hypergeometric distribution addGSLrngUIntUIntUIntFuncInt (SYM(rng_hypergeometric),SYM(n1),SYM(n2),SYM(t)); addGSLUIntUIntUIntUIntFunc (SYM(pdf_hypergeometric),SYM(k),SYM(n1),SYM(n2),SYM(t)); addGSLUIntUIntUIntUIntFunc (SYM(cdf_hypergeometric_P),SYM(k),SYM(n1),SYM(n2),SYM(t)); addGSLUIntUIntUIntUIntFunc (SYM(cdf_hypergeometric_Q),SYM(k),SYM(n1),SYM(n2),SYM(t)); } } // namespace trans #endif