From 0e1b013af77442311cd3708ec4bdbedb197a28e2 Mon Sep 17 00:00:00 2001 From: Thomas Grill Date: Fri, 14 Mar 2003 04:36:57 +0000 Subject: "" svn path=/trunk/; revision=468 --- externals/grill/vasp/source/opfuns.h | 378 +++++++++++++++++++++++++++++++++++ 1 file changed, 378 insertions(+) create mode 100644 externals/grill/vasp/source/opfuns.h (limited to 'externals/grill/vasp/source/opfuns.h') diff --git a/externals/grill/vasp/source/opfuns.h b/externals/grill/vasp/source/opfuns.h new file mode 100644 index 00000000..99fca899 --- /dev/null +++ b/externals/grill/vasp/source/opfuns.h @@ -0,0 +1,378 @@ +/* + +VASP modular - vector assembling signal processor / objects for Max/MSP and PD + +Copyright (c) 2002 Thomas Grill (xovo@gmx.net) +For information on usage and redistribution, and for a DISCLAIMER OF ALL +WARRANTIES, see the file, "license.txt," in this distribution. + +*/ + +#ifndef __VASP_OPFUNS_H +#define __VASP_OPFUNS_H + +#include "opdefs.h" + +namespace VecOp { + + // assignment + + template class f_copy { + public: + static V run(T &v,T a) { v = a; } + static V cun(T &rv,T &iv,T ra,T ia) { rv = ra,iv = ia; } + }; + + template class f_set { + public: + static V rbin(T &v,T,T b) { v = b; } + static V cbin(T &rv,T &iv,T,T,T rb,T ib) { rv = rb,iv = ib; } + }; + + // arithmetic + + template class f_add { + public: + static V rbin(T &v,T a,T b) { v = a+b; } + static V cbin(T &rv,T &iv,T ra,T ia,T rb,T ib) { rv = ra+rb,iv = ia+ib; } + }; + + template class f_sub { + public: + static V rbin(T &v,T a,T b) { v = a-b; } + static V cbin(T &rv,T &iv,T ra,T ia,T rb,T ib) { rv = ra-rb,iv = ia-ib; } + }; + + template class f_subr { + public: + static V rbin(T &v,T a,T b) { v = b-a; } + static V cbin(T &rv,T &iv,T ra,T ia,T rb,T ib) { rv = rb-ra,iv = ib-ia; } + }; + + template class f_mul { + public: + static V rbin(T &v,T a,T b) { v = a*b; } + static V cbin(T &rv,T &iv,T ra,T ia,T rb,T ib) { rv = ra*rb-ia*ib, iv = ra*ib+rb*ia; } + }; + + template class f_div { + public: + static V rbin(T &v,T a,T b) { v = a/b; } + + static V cbin(T &rv,T &iv,T ra,T ia,T rb,T ib) + { + register const R den = sqabs(rb,ib); + rv = (ra*rb+ia*ib)/den; + iv = (ia*rb-ra*ib)/den; + } + }; + + template class f_divr { + public: + static V rbin(T &v,T a,T b) { v = b/a; } + + static V cbin(T &rv,T &iv,T ra,T ia,T rb,T ib) + { + register const R den = sqabs(ra,ia); + rv = (rb*ra+ib*ia)/den; + iv = (ib*ra-rb*ia)/den; + } + }; + + template class f_mod { + public: + static V rbin(T &v,T a,T b) { v = fmod(a,b); } + }; + + template class f_abs { + public: + static V run(T &v,T a) { v = fabs(a); } + static V cun(T &rv,T &iv,T ra,T ia) { rv = sqrt(ra*ra+ia*ia),iv = 0; } + }; + + template class f_sign { + public: + static V run(T &v,T a) { v = (a == 0?0:(a < 0?-1.:1.)); } + }; + + template class f_sqr { + public: + static V run(T &v,T a) { v = a*a; } + static V cun(T &rv,T &iv,T ra,T ia) { rv = ra*ra-ia*ia; iv = ra*ia*2; } + }; + + template class f_ssqr { + public: + static V run(T &v,T a) { v = a*fabs(a); } + }; + + + // transcendent + + template class f_powi { + public: + static V cop(T &rv,T &iv,T ra,T ia,OpParam &p) + { + register const I powi = p.ibin.arg; + register S rt,it; f_sqr::cun(rt,it,ra,ia); + for(I i = 2; i < powi; ++i) f_mul::cbin(rt,it,rt,it,ra,ia); + rv = rt,iv = it; + } + }; + + template class f_pow { + public: + static V rbin(T &v,T a,T b) { v = pow(fabs(a),b)*sgn(a); } + + static V cbin(T &rv,T &iv,T ra,T ia,T rb,T) + { + register const R _abs = sqrt(sqabs(ra,ia)); + if(_abs) { + register const R _p = pow(_abs,rb)/_abs; + rv = _p*ra,iv = _p*ia; + } + else + rv = iv = 0; + } + }; + + template class f_sqrt { + public: + static V run(T &v,T a) { v = sqrt(fabs(a)); } + }; + + template class f_ssqrt { + public: + static V run(T &v,T a) { v = sqrt(fabs(a))*sgn(a); } + }; + + + template class f_exp { + public: + static V run(T &v,T a) { v = exp(a); } + }; + + template class f_log { + public: + static V run(T &v,T a) { v = log(a); } // \todo detect NANs + }; + + // comparisons + + template class f_lwr { + public: + static V rbin(T &v,T a,T b) { v = a < b?1:0; } + }; + + template class f_gtr { + public: + static V rbin(T &v,T a,T b) { v = a > b?1:0; } + }; + + template class f_alwr { + public: + static V rbin(T &v,T a,T b) { v = fabs(a) < fabs(b)?1:0; } + }; + + template class f_agtr { + public: + static V rbin(T &v,T a,T b) { v = fabs(a) > fabs(b)?1:0; } + }; + + template class f_leq { + public: + static V rbin(T &v,T a,T b) { v = a <= b?1:0; } + }; + + template class f_geq { + public: + static V rbin(T &v,T a,T b) { v = a >= b?1:0; } + }; + + template class f_aleq { + public: + static V rbin(T &v,T a,T b) { v = fabs(a) <= fabs(b)?1:0; } + }; + + template class f_ageq { + public: + static V rbin(T &v,T a,T b) { v = fabs(a) >= fabs(b)?1:0; } + }; + + template class f_equ { + public: + static V rbin(T &v,T a,T b) { v = a == b?1:0; } + }; + + template class f_neq { + public: + static V rbin(T &v,T a,T b) { v = a != b?1:0; } + }; + + // min/max + + template class f_min { + public: + static V rbin(T &v,T a,T b) { v = a < b?a:b; } + + static V cbin(T &rv,T &iv,T ra,T ia,T rb,T ib) + { + if(sqabs(ra,ia) < sqabs(rb,ib)) rv = ra,iv = ia; + else rv = rb,iv = ib; + } + }; + + template class f_max { + public: + static V rbin(T &v,T a,T b) { v = a > b?a:b; } + + static V cbin(T &rv,T &iv,T ra,T ia,T rb,T ib) + { + if(sqabs(ra,ia) > sqabs(rb,ib)) rv = ra,iv = ia; + else rv = rb,iv = ib; + } + }; + + template class f_minmax { + public: + static V cun(T &rv,T &iv,T ra,T ia) + { + if(ra < ia) rv = ra,iv = ia; + else rv = ia,iv = ra; + } + }; + + template class f_minq { + public: + static V rop(T &,T ra,OpParam &p) + { + if(ra < p.norm.minmax) p.norm.minmax = ra; + } + + static V cop(T &,T &,T ra,T ia,OpParam &p) + { + register T s = sqabs(ra,ia); + if(s < p.norm.minmax) p.norm.minmax = s; + } + }; + + template class f_maxq { + public: + static V rop(T &,T ra,OpParam &p) + { + if(ra > p.norm.minmax) p.norm.minmax = ra; + } + + static V cop(T &,T &,T ra,T ia,OpParam &p) + { + register T s = sqabs(ra,ia); + if(s > p.norm.minmax) p.norm.minmax = s; + } + }; + + template V f_aminq(T &,T ra,OpParam &p) + { + register T s = fabs(ra); + if(s < p.norm.minmax) p.norm.minmax = s; + } + + template V f_amaxq(T &,T ra,OpParam &p) + { + register T s = fabs(ra); + if(s > p.norm.minmax) p.norm.minmax = s; + } + + + // gating + + template class f_gate { + public: + static V rbin(T &rv,T ra,T rb) { rv = fabs(ra) >= rb?ra:0; } + + static V cbin(T &rv,T &iv,T ra,T ia,T rb,T) + { + register const T _abs = sqabs(ra,ia); + + if(_abs >= rb*rb) rv = ra,iv = ia; + else rv = iv = 0; + } + }; + + template class f_igate { + public: + static V rbin(T &rv,T ra,T rb) { rv = fabs(ra) <= rb?ra:0; } + + static V cbin(T &rv,T &iv,T ra,T ia,T rb,T) + { + register const T _abs = sqabs(ra,ia); + + if(_abs <= rb*rb) rv = ra,iv = ia; + else rv = iv = 0; + } + }; + + // complex + + template class f_norm { + public: + static V cun(T &rv,T &iv,T ra,T ia) + { + register T f = sqabs(ra,ia); + if(f) { f = 1./sqrt(f); rv = ra*f,iv = ia*f; } + else rv = iv = 0; + } + }; + + template class f_conj { + public: + static V cun(T &,T &iv,T,T ia) { iv = -ia; } + }; + + template class f_polar { + public: + static V cun(T &rv,T &iv,T ra,T ia) { rv = sqrt(sqabs(ra,ia)),iv = arg(ra,ia); } + }; + + template class f_rect { + public: + static V cun(T &rv,T &iv,T ra,T ia) { rv = ra*cos(ia),iv = ra*sin(ia); } + }; + + template class f_radd { + public: + static V cbin(T &rv,T &iv,T ra,T ia,T rb,T) + { + register const R _abs = sqrt(sqabs(ra,ia))+rb; + register const R _phi = arg(ra,ia); + + rv = _abs*cos(_phi),iv = _abs*sin(_phi); + } + }; + + // extra + + template class f_fix { + public: + /*! \brief Bashes denormals and NANs to zero + + \param a argument list + \param v destination vasp (NULL for in-place operation) + \return normalized destination vasp + */ + static V run(T &v,T a) + { + if(a != a) // NAN + v = 0; + else { + // denormal bashing (doesn't propagate to the next stage) + + static const F anti_denormal = 1e-18F; + a += anti_denormal; + a -= anti_denormal; + v = a; + } + } + }; +} + +#endif -- cgit v1.2.1