00001 #ifndef SYNAPS_SHAPE_ARRAY_OPS_H
00002 #define SYNAPS_SHAPE_ARRAY_OPS_H
00003
00004 #include <iostream>
00005 #include <stdlib.h>
00006 #include <realroot/texp_ringof.hpp>
00007
00008 namespace mmx {
00009
00010 template<typename A, typename B, unsigned N> inline
00011 void add( A (&a)[N], const B (&b)[N] )
00012 { for ( unsigned i = 0; i < N; a[i] += b[i], i++ ); };
00013
00014 template<typename A, typename B, typename C, unsigned N> inline
00015 void add( A (&a)[N], const B (&b)[N], const C (&c)[N] )
00016 { for ( unsigned i = 0; i < N; a[i] = b[i]+c[i], i ++); };
00017
00018 template<typename A, typename B, unsigned N> inline
00019 void sub( A (&a)[N], const B (&b)[N] )
00020 { for ( unsigned i = 0; i < N; a[i] -= b[i], i++ ); };
00021
00022 template<typename A, typename B, typename C, unsigned N> inline
00023 void sub( A (&a)[N], const B (&b)[N], const C (&c)[N] )
00024 { for ( unsigned i = 0; i < N; a[i] = b[i]-c[i], i ++); };
00025
00026 template<typename A, typename C, unsigned N> inline
00027 void scmul( A (&a)[N], const C& c )
00028 { for ( unsigned i = 0; i < N; a[i] *= c, i ++ ); };
00029
00030 template<typename A, typename B, unsigned N, typename W> inline
00031 void scmul( A (&a)[N], const B (&b)[N], const W& c )
00032 { for ( unsigned i = 0; i < N; a[i] = b[i]*c, i ++ ); };
00033
00034 template<typename A, typename B, unsigned N> inline
00035 void scdiv( A (&a)[N], const B& s )
00036 { for ( unsigned i = 0; i < N; a[i] /= s, i ++ ); };
00037
00038 template<typename A, typename B, unsigned N, typename W> inline
00039 void scdiv( A (&a)[N], const B (&b)[N], const W& c )
00040 { for ( unsigned i = 0; i < N; a[i] = b[i]/c, i ++ ); };
00041
00042 template<typename A, typename B, unsigned N> inline
00043 typename texp::ringof<A,B>::T dotprod( const A (&a)[N], const B (&b)[N] )
00044 {
00045 typename texp::ringof<A,B>::T res(0);
00046 for ( unsigned i = 0; i < N; res += a[i]*b[i], i ++ );
00047 return res;
00048 };
00049
00050 template<class C, unsigned N> inline
00051 C norm( const C (&v)[N], int p )
00052 {
00053 C a(0);
00054 for ( unsigned i = 0; i < N; a += pow(v[i],p), i ++ );
00055 return pow(a,C(1)/p);
00056 };
00057
00058 template<class A, class B, unsigned N> inline
00059 void init( const A (&v)[N], const B& k )
00060 { for ( unsigned i = 0; i < N; v[i++] = k ); };
00061
00062 template<class A, class B, unsigned N> inline
00063 void copy( const A (&a)[N], const B (&b)[N] )
00064 {
00065 for ( unsigned i = 0; i < N; i ++ ) a[i] = b[i];
00066 };
00067
00068 template<class C, unsigned N> inline
00069 void print( std::ostream & o, const C (&a)[N] )
00070 {
00071 o << "{";
00072 for ( unsigned i = 0; i < N-1; i ++ ) o << a[i] << ",";
00073 o << a[N-1];
00074 o << "}";
00075 };
00076
00077 template<class C, unsigned N> inline
00078 void urand( C (&v)[N], const C & a, const C & b )
00079 {
00080 for ( int i = 0; i < N; i ++ )
00081 {
00082 v[i] = ((double)rand()/RAND_MAX)*(b-a)+a ;
00083 };
00084 };
00085
00086 template<class C, unsigned N> inline
00087 bool eqxual( const C (&a)[N], const C (&b)[N] )
00088 {
00089 for ( int i = 0; i < N; i ++ ) if ( a[i] != b[i] ) return false;
00090 return true;
00091 };
00092
00093
00094 template<class C, unsigned N> inline
00095 const C & squared_distance( const C (&a)[N], const C (&b)[N] )
00096 {
00097 C s(0);
00098 C sv;
00099 for ( int i = 0; i < N; i ++ ) { sv = b[i]-a[i]; s += sv*sv; };
00100 return s;
00101 };
00102
00103 template<class C, unsigned N> inline
00104 const C & distance( const C (&a)[N], const C (&b)[N] )
00105 {
00106 return sqrt(squared_distance(a,b));
00107 };
00108 }
00109
00110 #endif