1 /////////////////////////////////////////////////////////////////////////////// 2 // // 3 // The Template Matrix/Vector Library for C++ was created by Mike Jarvis // 4 // Copyright (C) 1998 - 2016 // 5 // All rights reserved // 6 // // 7 // The project is hosted at https://code.google.com/p/tmv-cpp/ // 8 // where you can find the current version and current documention. // 9 // // 10 // For concerns or problems with the software, Mike may be contacted at // 11 // mike_jarvis17 [at] gmail. // 12 // // 13 // This software is licensed under a FreeBSD license. The file // 14 // TMV_LICENSE should have bee included with this distribution. // 15 // It not, you can get a copy from https://code.google.com/p/tmv-cpp/. // 16 // // 17 // Essentially, you can use this software however you want provided that // 18 // you include the TMV_LICENSE file in any distribution that uses it. // 19 // // 20 /////////////////////////////////////////////////////////////////////////////// 21 22 23 #ifndef TMV_SmallVectorArithFunc_H 24 #define TMV_SmallVectorArithFunc_H 25 26 #define CT std::complex<T> 27 28 namespace tmv { 29 30 template <typename T1, typename T2> 31 struct OKTypeHelper { enum { ok=true }; }; 32 template <typename T> 33 struct OKTypeHelper<CT,T> { enum { ok=false }; }; 34 35 template <typename T1, typename T2, typename T3> 36 struct OKTypeHelper2 { enum { ok=true }; }; 37 template <typename T> 38 struct OKTypeHelper2<T,CT,T> { enum { ok=false }; }; 39 template <typename T> 40 struct OKTypeHelper2<CT,T,T> { enum { ok=false }; }; 41 template <typename T> 42 struct OKTypeHelper2<CT,CT,T> { enum { ok=false }; }; 43 44 #define OKTypes(T1,T2) (OKTypeHelper<T1,T2>::ok) 45 #define OKTypes2(T1,T2,T3) (OKTypeHelper2<T1,T2,T3>::ok) 46 47 48 // v *= x 49 template <ptrdiff_t N, typename T, typename Tv, bool ok> 50 struct MultXVHelper 51 { MultXVHelper(const T, Tv*) {} }; 52 template <ptrdiff_t N, typename T, typename Tv> 53 struct MultXVHelper<N,T,Tv,true> 54 { 55 MultXVHelper(const T x, Tv* v) 56 { for(ptrdiff_t i=0;i<N;++i) v[i] *= x; } 57 }; 58 template <ptrdiff_t N, typename T, typename Tv> 59 inline void MultXV(const T x, Tv* v) 60 { MultXVHelper<N,T,Tv,OKTypes(T,Tv)>(x,v); } 61 62 // v2 = x * v1 63 template <ptrdiff_t N, typename T, typename T1, typename T2, bool ok> 64 struct MultXVHelper2 65 { MultXVHelper2(const T, const T1*, T2*) {} }; 66 template <ptrdiff_t N, typename T, typename T1, typename T2> 67 struct MultXVHelper2<N,T,T1,T2,true> 68 { 69 MultXVHelper2(const T x, const T1* v1, T2* v2) 70 { for(ptrdiff_t i=0;i<N;++i) v2[i] = x * v1[i]; } 71 }; 72 template <ptrdiff_t N, typename T, typename T1, typename T2> 73 inline void MultXV( const T x, const T1* v1, T2* v2) 74 { MultXVHelper2<N,T,T1,T2,OKTypes2(T,T1,T2)>(x,v1,v2); } 75 76 // v2 += x * v1 77 template <ptrdiff_t N, typename T1, typename T2, bool ok> 78 struct AddVV_1Helper 79 { AddVV_1Helper(const T1*, T2*) {} }; 80 template <ptrdiff_t N, typename T1, typename T2> 81 struct AddVV_1Helper<N,T1,T2,true> 82 { 83 inline AddVV_1Helper(const T1* v1, T2* v2) 84 { for(ptrdiff_t i=0;i<N;++i) v2[i] += v1[i]; } 85 }; 86 template <ptrdiff_t N, typename T1, typename T2> 87 inline void AddVV_1(const T1* v1, T2* v2) 88 { AddVV_1Helper<N,T1,T2,OKTypes(T1,T2)>(v1,v2); } 89 90 template <ptrdiff_t N, typename T1, typename T2, bool ok> 91 struct AddVV_m1Helper 92 { AddVV_m1Helper(const T1*, T2*) {} }; 93 template <ptrdiff_t N, typename T1, typename T2> 94 struct AddVV_m1Helper<N,T1,T2,true> 95 { 96 inline AddVV_m1Helper(const T1* v1, T2* v2) 97 { for(ptrdiff_t i=0;i<N;++i) v2[i] -= v1[i]; } 98 }; 99 template <ptrdiff_t N, typename T1, typename T2> 100 inline void AddVV_m1(const T1* v1, T2* v2) 101 { AddVV_m1Helper<N,T1,T2,OKTypes(T1,T2)>(v1,v2); } 102 103 template <ptrdiff_t N, typename T, typename T1, typename T2, bool ok> 104 struct AddVVHelper 105 { AddVVHelper(const T, const T1*, T2*) {} }; 106 template <ptrdiff_t N, typename T, typename T1, typename T2> 107 struct AddVVHelper<N,T,T1,T2,true> 108 { 109 inline AddVVHelper(const T x, const T1* v1, T2* v2) 110 { for(ptrdiff_t i=0;i<N;++i) v2[i] += x*v1[i]; } 111 }; 112 template <ptrdiff_t N, typename T, typename T1, typename T2> 113 inline void AddVV(const T x, const T1* v1, T2* v2) 114 { AddVVHelper<N,T,T1,T2,OKTypes2(T,T1,T2)>(x,v1,v2); } 115 116 // v3 = x1 * v1 + x2 * v2 117 template <ptrdiff_t N, typename T1, typename T2, typename T3> 118 inline void AddVV_1_1(const T1* v1, const T2* v2, T3* v3) 119 { SmallVectorCopy<N>(v1,v3); AddVV_1<N>(v2,v3); } 120 template <ptrdiff_t N, typename T1, typename T2, typename T3> 121 inline void AddVV_1_m1(const T1* v1, const T2* v2, T3* v3) 122 { SmallVectorCopy<N>(v1,v3); AddVV_m1<N>(v2,v3); } 123 template <ptrdiff_t N, typename T, typename T1, typename T2, typename T3> 124 inline void AddVV_1_x(const T1* v1, const T x2, const T2* v2, T3* v3) 125 { MultXV<N>(x2,v2,v3); AddVV_1<N>(v1,v3); } 126 template <ptrdiff_t N, typename T, typename T1, typename T2, typename T3> 127 inline void AddVV_x_1(const T x1, const T1* v1, const T2* v2, T3* v3) 128 { MultXV<N>(x1,v1,v3); AddVV_1<N>(v2,v3); } 129 template <ptrdiff_t N, typename T, typename T1, typename T2, typename T3> 130 inline void AddVV_x_m1(const T x1, const T1* v1, const T2* v2, T3* v3) 131 { MultXV<N>(x1,v1,v3); AddVV_m1<N>(v2,v3); } 132 template <ptrdiff_t N, typename T, typename T1, typename T2, typename T3> 133 inline void AddVV(const T x1, const T1* v1, const T x2, const T2* v2, T3* v3) 134 { MultXV<N>(x1,v1,v3); AddVV<N>(x2,v2,v3); } 135 136 // v1 * v2 (dot product) 137 template <typename T1, typename T2> 138 struct ProdType { typedef T1 Tprod; }; 139 template <typename T> 140 struct ProdType<T,std::complex<T> > { typedef std::complex<T> Tprod; }; 141 #define ProductType(T1,T2) typename ProdType<T1,T2>::Tprod 142 143 template <ptrdiff_t N, typename T, typename T1, typename T2> 144 struct MultVVHelper 145 { 146 inline MultVVHelper(T& res, const T1* v1, const T2* v2) 147 { for(ptrdiff_t i=0;i<N;++i) res += v1[i]*v2[i]; } 148 }; 149 template <ptrdiff_t N, typename T1, typename T2> 150 inline ProductType(T1,T2) MultVV(const T1* v1, const T2* v2) 151 { 152 ProductType(T1,T2) res(0); 153 MultVVHelper<N,ProductType(T1,T2),T1,T2>(res,v1,v2); 154 return res; 155 } 156 #undef ProductType 157 158 template <typename T, typename T1, typename T2, typename T3, ptrdiff_t N, int A1, int A2, int A3> 159 inline void ElemMultVV( 160 const T alpha, const SmallVector<T1,N,A1>& v1, 161 const SmallVector<T2,N,A2>& v2, SmallVector<T3,N,A3>& v3) 162 { 163 if (alpha == T(1)) 164 for(ptrdiff_t i=0;i<N;++i) v3.ref(i) = v1.cref(i) * v2.cref(i); 165 else 166 for(ptrdiff_t i=0;i<N;++i) v3.ref(i) = alpha * v1.cref(i) * v2.cref(i); 167 } 168 template <typename T, typename T1, typename T2, ptrdiff_t N, int A1, int A2, int A3> 169 inline void ElemMultVV( 170 const CT , const SmallVector<T1,N,A1>& , 171 const SmallVector<T2,N,A2>& , SmallVector<T,N,A3>& ) 172 { TMVAssert(TMV_FALSE); } 173 174 175 template <typename T, typename T1, typename T2, typename T3, ptrdiff_t N, int A1, int A2, int A3> 176 inline void AddElemMultVV( 177 const T alpha, const SmallVector<T1,N,A1>& v1, 178 const SmallVector<T2,N,A2>& v2, SmallVector<T3,N,A3>& v3) 179 { 180 if (alpha == T(1)) 181 for(ptrdiff_t i=0;i<N;++i) v3.ref(i) += v1.cref(i) * v2.cref(i); 182 else if (alpha == T(-1)) 183 for(ptrdiff_t i=0;i<N;++i) v3.ref(i) -= v1.cref(i) * v2.cref(i); 184 else 185 for(ptrdiff_t i=0;i<N;++i) v3.ref(i) += alpha * v1.cref(i) * v2.cref(i); 186 } 187 template <typename T, typename T1, typename T2, ptrdiff_t N, int A1, int A2, int A3> 188 inline void AddElemMultVV( 189 const CT , const SmallVector<T1,N,A1>& , 190 const SmallVector<T2,N,A2>& , SmallVector<T,N,A3>& ) 191 { TMVAssert(TMV_FALSE); } 192 193 #undef OKTypes 194 #undef OKTypes2 195 196 } // namespace tmv 197 198 #undef CT 199 200 #endif 201