shape_doc 0.1
/Users/mourrain/Devel/mmx/shape/include/shape/fxv.hpp
Go to the documentation of this file.
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