00001 #ifndef SYNAPS_VECTOR_FXV_H
00002 #define SYNAPS_VECTOR_FXV_H
00003 #include <shape/ssi/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
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);
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 }
00260
00261 #endif