shape_doc 0.1
|
00001 #ifndef SYNAPS_VECTOR_FXV_H 00002 #define SYNAPS_VECTOR_FXV_H 00003 #include <shape/ssi_base_array_ops.hpp> 00004 #include <realroot/assign.hpp> 00005 #include <realroot/texp_expression.hpp> 00006 #include <realroot/texp_operators.hpp> 00007 #include <vector> 00008 00009 namespace mmx { 00010 00011 struct fxv_empty {}; 00012 inline std::ostream & operator<<( std::ostream & o, const fxv_empty & ) { return o; }; 00013 00014 template<class C, unsigned N, class H> struct fxv; 00015 template<class C, unsigned N> 00016 struct fxv_dlink 00017 { 00018 fxv< C, N, fxv_dlink > * l0, * l1; 00019 fxv_dlink() : l0(0), l1(0){}; 00020 }; 00021 00022 template<class C, unsigned N> 00023 std::ostream& operator<<( std::ostream & o, const fxv_dlink<C,N>& a ) 00024 { 00025 o << a.l0 << ", " << a.l1 << std::endl; return o; 00026 }; 00027 00028 template< typename C, unsigned N, class H = fxv_empty > 00029 struct fxv : H 00030 { 00031 typedef fxv<C,N,H> self_t; 00032 static const int _dimension_ = N; 00033 typedef C value_type; 00034 C data[N]; 00035 C& operator[]( unsigned i ) { return data[i]; }; 00036 const C& operator[]( unsigned i ) const { return data[i]; }; 00037 template<typename K,class H2> 00038 fxv& operator=( const fxv<K,N,H2>& v ); 00039 self_t & operator=(const C& x ); 00040 template<class S> 00041 self_t & operator=(const texp::template_expression<S> & M) 00042 { 00043 using namespace let; 00044 assign(*this,M); 00045 return *this; 00046 }; 00047 bool operator==(int n) const; 00048 bool operator!=(int n) const {return !(*this==n);} 00049 bool operator==(const self_t & p) const; 00050 bool operator!=(const self_t & p) const {return !(*this==p);} 00051 template<class X> self_t& operator+=(const X& x) { add(*this,x); return *this; }; 00052 template<class X> self_t& operator-=(const X& x) { sub(*this,x); return *this; }; 00053 template<class X> self_t& operator*=(const X& x) { mul(*this,x); return *this; }; 00054 template<class X> self_t& operator/=(const X& x) { div(*this,x); return *this; }; 00055 template<class X> self_t& operator%=(const X& x) { mod(*this,x); return *this; }; 00056 }; 00057 00058 00059 template<typename C, unsigned N, class H> inline 00060 void add( fxv<C,N,H>& a, const fxv<C,N,H>& b ) { add(a.data,b.data); }; 00061 template<typename C, unsigned N, class H> inline 00062 void add( fxv<C,N,H>& a, const fxv<C,N,H>& b, const fxv<C,N,H>& c ) { add(a.data,b.data,c.data); }; 00063 template<typename C, unsigned N, class H> inline 00064 void sub( fxv<C,N,H>& a, const fxv<C,N,H>& b ) { sub(a.data,b.data); }; 00065 template<typename C, unsigned N, class H> inline 00066 void sub( fxv<C,N,H>& a, const fxv<C,N,H>& b, const fxv<C,N,H>& c) { sub(a.data,b.data,c.data); }; 00067 template<typename C, unsigned N, class H> inline 00068 void scmul( fxv<C,N,H>& a, const C& c ) { scmul(a.data,c); }; 00069 template<typename C, unsigned N, class H> inline 00070 void scmul( fxv<C,N,H>& a, const fxv<C,N,H>& b, const C& c ) { scmul(a.data,b.data,c); }; 00071 template<typename A, typename B, unsigned N> inline 00072 void scdiv( fxv<A,N>& a, const B& s ) { scdiv(a.data,s); }; 00073 template<typename C, unsigned N, class H> inline 00074 void scdiv( fxv<C,N,H>& a, const fxv<C,N,H>& b, const C& s ) { scdiv(a.data,b.data,s); }; 00075 template<typename C, unsigned N, class H> inline 00076 C dotprod( const fxv<C,N,H>& a, const fxv<C,N,H>& b ) { return dotprod(a.data,b.data); }; 00077 template<class C, unsigned N,class H> inline 00078 C norm( const fxv<C,N,H>& v, int p ) { return norm(v.data,p); }; 00079 template<class A, class B, unsigned N> inline 00080 void init( const fxv<A,N>& v, const B& k ) { init(v.data,k); }; 00081 template<typename C, typename H> inline 00082 void crossprod( fxv<C,3,H>& res, const fxv<C,3,H>& a, const fxv<C,3,H>& b ) 00083 { res[0]=a[1]*b[2]-b[1]*a[2]; res[1]=a[2]*b[0]-b[2]*a[0]; res[2]=a[0]*b[1]-b[0]*a[1]; }; 00084 template<typename C, unsigned N, class H> inline 00085 void add( fxv<C,N,H>& a, const C& c ) { scadd(a,c); }; 00086 00087 template<typename C, unsigned N, class H> 00088 void add( fxv<C,N,H>& a, const fxv<C,N,H>& b, const C& c ) { scadd(a,b,c); }; 00089 00090 template<typename C, unsigned N, class H> inline 00091 void sub( fxv<C,N,H>& a, const C& c ) { scsub(a,c); }; 00092 00093 template<typename C, unsigned N, class H> inline 00094 void mul( fxv<C,N,H>& a, const C& c ) { scmul(a,c); }; 00095 00096 template<typename C, unsigned N, class H> inline 00097 void mul( fxv<C,N,H>& a, const fxv<C,N,H>& b, const C& c ) { scmul(a.data,b.data,c); }; 00098 00099 template<typename C, unsigned N, class H> inline 00100 void mul( fxv<C,N,H>& a, const C& c, const fxv<C,N,H>& b ) { scmul(a.data,b.data,c); }; 00101 00102 template<typename C, unsigned N, class H> inline 00103 void mul( C& r, const fxv<C,N,H>& a, const fxv<C,N,H>& b ) { r = dotprod(a,b); }; 00104 00105 template<typename C, unsigned N, class H> inline 00106 void div( fxv<C,N,H>& a, const C& s ) { scdiv(a.data,s); }; 00107 00108 template<typename C, unsigned N, class H> inline 00109 void div( fxv<C,N,H>& a, const fxv<C,N,H>& b, const C& s ) { scdiv(a.data,b.data,s); }; 00110 00111 template<typename C, unsigned N, class H> inline 00112 void mod( fxv<C,N,H>& a, const fxv<C,N,H>& b, const fxv<C,N,H>& c ) { a = b-((b*c)/(c*c))*c; }; 00113 00114 template<typename C, unsigned N, class R > inline 00115 C norm2( const fxv<C,N,R>& v ) { return dotprod(v,v); }; 00116 00117 template<typename C, unsigned N, class H > inline 00118 C norm( const fxv<C,N,H>& v ) { return sqrt(norm2(v)); }; 00119 00120 template<typename C, unsigned N, class H > inline 00121 C max( const fxv<C,N,H>& v ) { return max(v.data); }; 00122 00123 template<typename C, unsigned N, class H > inline 00124 C min( const fxv<C,N,H>& v ) { return min(v); }; 00125 00126 template<typename C, unsigned N, class H> inline 00127 void urand( fxv<C,N,H>& v, const C& a = (C)0.0, const C& b = (C)1.0 ) { urand(v.data,a,b); }; 00128 00129 template<typename C, unsigned N, class H> inline 00130 std::ostream& operator<<( std::ostream& o, const fxv<C,N,H>& v ) { 00131 o << *((const H*)&v); 00132 o << "[ data = "; 00133 print(o,v.data); 00134 o << "]"; 00135 return o; 00136 }; 00137 00138 template<typename C, unsigned N, class H> inline 00139 void init( fxv<C,N,H>& v, const C& k ) { init(v.rep(),k); }; 00140 00141 00142 namespace texp { 00143 00144 template<typename Ca,typename Cb,unsigned N,class H> 00145 struct ringof< fxv< Ca, N, H >, fxv< Cb, N, H > > { typedef fxv< typename ringof<Ca,Cb>::T,N,H> T; }; 00146 template<typename Ca,typename Cb,unsigned N,class H> 00147 struct binary_operator_prototype< _mul_, fxv<Ca,N,H>, fxv<Cb,N,H> > 00148 { 00149 typedef typename ringof< fxv<Ca,N,H>, fxv<Cb,N,H> >::T U; 00150 typedef U V; 00151 typedef typename U::value_type F; 00152 }; 00153 // scalar * vector prototype. 00154 template < typename Ca, typename Cb, unsigned N, class H > 00155 struct binary_operator_prototype< _mul_, fxv<Ca,N,H>, Cb > 00156 { 00157 typedef typename ringof<Ca,Cb>::T C; 00158 typedef C V; 00159 typedef fxv<C,N,H> F; 00160 typedef F U; 00161 }; 00162 00163 template < typename Ca, typename Cb, unsigned N, class H > 00164 struct binary_operator_prototype< _div_, fxv<Ca,N,H>, Cb > 00165 { 00166 typedef typename fieldof<Ca,Cb>::T C; 00167 typedef C V; 00168 typedef fxv<C,N,H> F; 00169 typedef F U; 00170 }; 00171 00172 template < typename Ca, typename Cb, unsigned N, class H > 00173 struct binary_operator_prototype< _div_, Cb, fxv<Ca,N,H> > 00174 { 00175 typedef binary_operator_prototype< _div_, fxv<Ca,N,H >, Cb > X; 00176 typedef typename X::V U; 00177 typedef typename X::U V; 00178 typedef typename X::F F; 00179 }; 00180 00181 template < typename Ca, typename Cb, unsigned N, class H > 00182 struct binary_operator_prototype< _mul_, Cb, fxv<Ca,N,H> > 00183 { 00184 typedef binary_operator_prototype< _mul_, fxv<Ca,N,H >, Cb > X; 00185 typedef typename X::V U; 00186 typedef typename X::U V; 00187 typedef typename X::F F; 00188 }; 00189 }; 00190 00191 template<class C, unsigned N, class H> 00192 bool fxv<C,N,H>::operator==(const fxv<C,N,H>& v ) const 00193 { 00194 return eqxual(this->data,v.data); // type::equal 00195 }; 00196 00197 template<class C, unsigned N, class H> 00198 template<typename C2,class H2> 00199 fxv<C,N,H>& fxv<C,N,H>::operator=( const fxv<C2,N,H2>& v ) { copy(this->data,v.data); }; 00200 00201 template<class C, unsigned N, class H> 00202 C max_abs( const fxv<C,N,H> & v ) 00203 { 00204 using std::abs; 00205 C s(abs(v[0])); 00206 for ( unsigned i = 1; i < N; i ++ ) 00207 s = std::max(s,abs(v[i])); 00208 return s; 00209 }; 00210 00211 template<class C, unsigned N, class H> inline 00212 const C & distance( const fxv<C,N,H> & a, const fxv<C,N,H> & b ) 00213 { 00214 return distance(a.data,b.data); 00215 }; 00216 00217 namespace texp 00218 { 00219 template<class C, int N, class H> 00220 struct structureof< fxv<C,N,H> > { typedef structure::vector T ; }; 00221 }; 00222 #define head template<typename Ca,typename Cb,unsigned N,class H> 00223 #define parm0 fxv<Ca,N,H> 00224 #define parm1 fxv<Cb,N,H> 00225 declare_binary_operator(head,parm0,parm1,texp::_add_,operator+); 00226 declare_binary_operator(head,parm0,parm1,texp::_add_,operator-); 00227 declare_binary_operator(head,parm0,parm1,texp::_mul_,operator*); 00228 #undef head 00229 #define head template<class C,unsigned N, class H> 00230 #undef parm0 00231 #define parm0 fxv<C,N,H> 00232 #undef parm1 00233 #define parm1 typename fxv<C,N,H>::value_type 00234 declare_binary_operator(head,parm0,parm1,texp::_mul_,operator*); 00235 declare_binary_operator(head,parm1,parm0,texp::_mul_,operator*); 00236 declare_binary_operator(head,parm0,parm1,texp::_div_,operator/); 00237 #undef parm1 00238 #undef head 00239 #define head template<class C, class H, class K, unsigned N> 00240 #define parm1 typename K::integer 00241 declare_binary_operator(head,parm0,parm1,texp::_mul_,operator*); 00242 declare_binary_operator(head,parm1,parm0,texp::_mul_,operator*); 00243 declare_binary_operator(head,parm0,parm1,texp::_div_,operator/); 00244 #undef parm1 00245 #define parm1 typename K::rational 00246 declare_binary_operator(head,parm0,parm1,texp::_mul_,operator*); 00247 declare_binary_operator(head,parm1,parm0,texp::_mul_,operator*); 00248 declare_binary_operator(head,parm0,parm1,texp::_div_,operator/); 00249 #undef parm1 00250 #define parm1 typename K::floating 00251 declare_binary_operator(head,parm0,parm1,texp::_mul_,operator*); 00252 declare_binary_operator(head,parm1,parm0,texp::_mul_,operator*); 00253 declare_binary_operator(head,parm0,parm1,texp::_div_,operator/); 00254 #undef head 00255 #undef parm0 00256 #undef parm1 00257 00258 00259 } //namespace mmx 00260 00261 #endif