00001 #ifndef UTIL_H 00002 #define UTIL_H 00003 00004 #ifndef TOON_NO_NAMESPACE 00005 namespace TooN { 00006 #endif 00007 namespace util { 00008 00009 template <bool Cond> struct Assert; 00010 template <> struct Assert<true> {}; 00011 00012 template <int B, int E, bool Valid=(B<=E)> struct Dot { 00013 template <class V1, class V2> static inline double eval(const V1& v1, const V2& v2) { return 0; } 00014 }; 00015 00016 template <int B, int E> struct Dot<B,E,true> { 00017 template <class V1, class V2> static inline double eval(const V1& v1, const V2& v2) { return v1[B]* v2[B] + Dot<B+1,E>::eval(v1,v2); } 00018 }; 00019 00020 template <int N> struct Dot<N,N,true> { 00021 template <class V1, class V2> static inline double eval(const V1& v1, const V2& v2) { return v1[N]*v2[N]; } 00022 }; 00023 00024 00025 template <int B, int E> struct AddV { 00026 template <class V1, class V2> static inline void eval(V1& v1, const V2& v2) { v1[B]+=v2[B]; AddV<B+1,E>::eval(v1,v2); } 00027 }; 00028 00029 template <int N> struct AddV<N,N> { 00030 template <class V1, class V2> static inline void eval(V1& v1, const V2& v2) { v1[N] += v2[N]; } 00031 }; 00032 00033 #if 0 00034 template <int A, int N, int B, int Row, int Col=0> struct MatrixProductRow { 00035 template <class M1, class M2, class V> static inline void eval(const M1& a, const M2& b, V& v) { 00036 v[Col] = Dot<0,N-1>::eval(a[Row], b[Col]); 00037 MatrixProductRow<A,N,B,Row,Col+1>::eval(a,b,v); 00038 } 00039 }; 00040 00041 template <int A, int N, int B, int Row> struct MatrixProductRow<A,N,B,Row,B> { 00042 template <class M1, class M2, class V> static inline void eval(const M1& a, const M2& b, V& v) { 00043 v[B] = Dot<0,N-1>::eval(a[Row], b[B]); 00044 } 00045 }; 00046 00047 template <int A, int N, int B, int Row=0> struct MatrixProduct { 00048 template <class M1, class M2, class M3> static inline void eval(const M1& a, const M2& b, M3& m) { 00049 MatrixProductRow<A,N,B,Row>::eval(a,b,m[Row]); 00050 MatrixProduct<A,N,B,Row+1>::eval(a,b,m); 00051 } 00052 }; 00053 00054 template <int A, int N, int B> struct MatrixProduct<A,N,B,A> { 00055 template <class M1, class M2, class M3> static inline void eval(const M1& a, const M2& b, M3& m) { 00056 MatrixProductRow<A,N,B,A>::eval(a,b,m[A]); 00057 } 00058 }; 00059 00060 template <int A, int N, int B, class M1, class M2, class M3> inline void matrix_multiply(const M1& a, const M2& b, M3& m) { 00061 MatrixProduct<A-1,N,B-1>::eval(a,b.T(),m); 00062 } 00063 #endif 00064 00065 template <int B, int Col=0> struct MatrixProductRow { 00066 template <class F, class M1, class M2, class V> static inline void eval(const M1& a, const M2& b, V& v, int row) { 00067 F::eval(v[Col], a[row] * b[Col]); 00068 MatrixProductRow<B,Col+1>::template eval<F>(a,b,v, row); 00069 } 00070 }; 00071 00072 template <int B> struct MatrixProductRow<B,B> { 00073 template <class F, class M1, class M2, class V> static inline void eval(const M1& a, const M2& b, V& v, int row) { 00074 F::eval(v[B], a[row] * b[B]); 00075 } 00076 }; 00077 struct Assign { template <class LHS, class RHS> static inline void eval(LHS& lhs, const RHS& rhs) { lhs = rhs; } }; 00078 struct PlusEquals { template <class LHS, class RHS> static inline void eval(LHS& lhs, const RHS& rhs) { lhs += rhs; } }; 00079 struct MinusEquals { template <class LHS, class RHS> static inline void eval(LHS& lhs, const RHS& rhs) { lhs -= rhs; } }; 00080 00081 template <class F, int A, int N, int B, class M1, class M2, class M3> inline void matrix_multiply(const M1& a, const M2& b, M3& m) { 00082 for (int i=0; i<m.num_rows(); i++) 00083 MatrixProductRow<B-1>::template eval<F>(a,b.T(),m[i],i); 00084 } 00085 00086 template <int A, int N, int B, class M1, class M2, class M3> inline void matrix_multiply(const M1& a, const M2& b, M3& m) { 00087 matrix_multiply<Assign,A,N,B,M1,M2,M3>(a,b,m); 00088 } 00089 00090 } 00091 00092 00093 00094 #ifndef TOON_NO_NAMESPACE 00095 } 00096 #endif 00097 00098 00099 00100 00101 00102 #endif