00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #ifndef MORE_NUM_MATRIXALGO_H
00031 #define MORE_NUM_MATRIXALGO_H
00032
00033
00034 #include <iterator>
00035 #include <algorithm>
00036 #include <numeric>
00037 #include <stdexcept>
00038 #include <functional>
00039 #include <more/math/math.h>
00040 #include <more/bits/optype.h>
00041 #include <more/num/matrix.h>
00042
00043
00044 namespace more {
00045 namespace num {
00046
00047
00048
00049 template<typename T, typename Sig>
00050 inline matrix<T, Sig>
00051 operator+(const matrix<T, Sig>& A, const matrix<T, Sig>& B) {
00052 assert(A.size(0) == B.size(0) && A.size(1) == B.size(1));
00053 matrix<T, Sig> C(A.size(0), A.size(1));
00054 std::transform(A.begin(), A.end(), B.begin(), C.begin(),
00055 std::plus<T>());
00056 return C;
00057 }
00058 template<typename T, typename Sig>
00059 inline matrix<T, Sig>
00060 operator-(const matrix<T, Sig>& A, const matrix<T, Sig>& B) {
00061 assert(A.size(0) == B.size(0) && A.size(1) == B.size(1));
00062 matrix<T, Sig> C(A.size(0), A.size(1));
00063 std::transform(A.begin(), A.end(), B.begin(), C.begin(),
00064 std::minus<T>());
00065 return C;
00066 }
00067 template<typename T> inline
00068 typename scalar_type_<T>::eval trace(matrix<T> const& A) {
00069 typename scalar_type_<T>::eval tr = 0;
00070 assert(A.size(0) == A.size(1));
00071 for(int i = 0; i < A.size(0); ++i) tr += trace(A(i,i));
00072 return tr;
00073 }
00074
00075
00076
00077
00078 template<typename T>
00079 inline typename scalar_type_<T>::eval
00080 dot(mvector<T> const& A, mvector<T> const& B) {
00081 typedef typename mvector<T>::const_iterator iterator;
00082 if(A.size() != B.size())
00083 throw std::out_of_range(
00084 "dot product applied to vectors with different sizes");
00085 typename scalar_type_<T>::eval sum = zero;
00086 for(iterator u = A.begin(), v = B.begin(), uend = A.end();
00087 u != uend; ++u, ++v) sum += dot(*u, *v);
00088 return sum;
00089 }
00090
00091
00092
00093 template<typename T>
00094 inline typename norm_type_<T>::eval norm(const mvector<T>& A) {
00095 typedef typename mvector<T>::const_iterator iterator;
00096 typename norm_type_<T>::eval sum = zero;
00097 for(iterator u = A.begin(), uend = A.end();
00098 u != uend; ++u) sum += norm(*u);
00099 return sum;
00100 }
00101
00102 template<typename T>
00103 inline typename norm_type_<T>::eval
00104 abs(const mvector<T>& A) { return more::sqrt(norm(A)); }
00105
00106 template<typename T> inline T sum(const mvector<T>& x)
00107 { return std::accumulate(x.begin(), x.end(), (T)0); }
00108
00109 template<typename T> inline
00110 void normalize(mvector<T>& f) {
00111 norm_type_<T>::eval c = 0;
00112 for(int s = 0; s < f.size(); ++s) c += norm(f(s));
00113 c = 1/sqrt(c);
00114 for(int s = 0; s < f.size(); ++s) f(s) *= c;
00115 }
00116
00117 template<typename T> inline mvector<T>
00118 operator-(const mvector<T>& A, const mvector<T>& B) {
00119 assert(A.size(0) == B.size(0));
00120 mvector<T> C(A.size(0));
00121 std::transform(A.begin(), A.end(), B.begin(), C.begin(),
00122 std::minus<T>());
00123 return C;
00124 }
00125
00126 template<typename T> inline mvector<T>
00127 operator+(const mvector<T>& A, const mvector<T>& B) {
00128 assert(A.size(0) == B.size(0));
00129 mvector<T> C(A.size(0));
00130 std::transform(A.begin(), A.end(), B.begin(), C.begin(),
00131 std::plus<T>());
00132 return C;
00133 }
00134
00135 template<typename T, typename U>
00136 inline mvector< typename times_type_<T, U>::eval >
00137 operator*(const T& a, const mvector<U>& B) {
00138 typedef mvector< typename times_type_<T, U>::eval > vec_type;
00139 vec_type C(B.size(0));
00140 typename mvector<U>::const_iterator v = B.begin();
00141 for(typename vec_type::iterator u = C.begin(); u != C.end(); ++u) {
00142 *u = a * (*v);
00143 ++v;
00144 }
00145 return C;
00146 }
00147 }}
00148
00149
00150 #endif