00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef SGE_MATH_MATRIX_IMPL_HPP_INCLUDED
00022 #define SGE_MATH_MATRIX_IMPL_HPP_INCLUDED
00023
00024 #include "matrix.hpp"
00025 #include "compare.hpp"
00026 #include "../algorithm.hpp"
00027 #include "../exception.hpp"
00028 #include <algorithm>
00029 #include <functional>
00030 #include <ostream>
00031
00032 #ifdef SGE_HAVE_VARIADIC_TEMPLATES
00033 template<typename T, std::size_t N, std::size_t M>
00034 template<typename... Args>
00035 sge::math::basic_matrix<T, N, M>::basic_matrix(Args... args)
00036 {
00037 set(args...);
00038 }
00039 #endif
00040
00041 template<typename T, std::size_t N, std::size_t M>
00042 sge::math::basic_matrix<T, N, M>::basic_matrix(no_initialization_tag)
00043 {
00044 }
00045
00046 template<typename T, std::size_t N, std::size_t M>
00047 sge::math::basic_matrix<T, N, M>::basic_matrix(const basic_matrix& r)
00048 {
00049 copy_n(r.data_, size(), data_);
00050 }
00051
00052 template<typename T, std::size_t N, std::size_t M>
00053 typename sge::math::basic_matrix<T, N, M>&
00054 sge::math::basic_matrix<T, N, M>::operator=(const basic_matrix& r)
00055 {
00056 copy_n(r.data_, size(), data_);
00057 return *this;
00058 }
00059
00060 template<typename T, std::size_t N, std::size_t M>
00061 sge::math::basic_matrix<T, N, M>&
00062 sge::math::basic_matrix<T, N, M>::operator+=(const basic_matrix& r)
00063 {
00064 for(size_type i = 0; i < size(); ++i)
00065 data_[i] += r.data_[i];
00066 return *this;
00067 }
00068
00069 template<typename T, std::size_t N, std::size_t M>
00070 sge::math::basic_matrix<T, N, M>&
00071 sge::math::basic_matrix<T, N, M>::operator-=(const basic_matrix& r)
00072 {
00073 for(size_type i = 0; i < size(); ++i)
00074 data_[i] -= r.data_[i];
00075 return *this;
00076 }
00077
00078 template<typename T, std::size_t N, std::size_t M>
00079 sge::math::basic_matrix<T, N, M>&
00080 sge::math::basic_matrix<T, N, M>::operator*=(const value_type& v)
00081 {
00082 for(size_type i = 0; i < size(); ++i)
00083 data_[i] *= v;
00084 return *this;
00085 }
00086
00087 template<typename T, std::size_t N, std::size_t M>
00088 const typename sge::math::basic_matrix<T, N, M>::proxy
00089 sge::math::basic_matrix<T, N, M>::operator[](const size_type j)
00090 {
00091 return proxy(j,data());
00092 }
00093
00094 template<typename T, std::size_t N, std::size_t M>
00095 const typename sge::math::basic_matrix<T, N, M>::const_proxy
00096 sge::math::basic_matrix<T, N, M>::operator[](const size_type j) const
00097 {
00098 return const_proxy(j,data());
00099 }
00100
00101 template<typename T, std::size_t N, std::size_t M>
00102 typename sge::math::basic_matrix<T, N, M>::pointer
00103 sge::math::basic_matrix<T, N, M>::data()
00104 {
00105 return data_;
00106 }
00107
00108 template<typename T, std::size_t N, std::size_t M>
00109 typename sge::math::basic_matrix<T, N, M>::const_pointer
00110 sge::math::basic_matrix<T, N, M>::data() const
00111 {
00112 return data_;
00113 }
00114
00115 template<typename T, std::size_t N, std::size_t M>
00116 typename sge::math::basic_matrix<T, N, M>::size_type
00117 sge::math::basic_matrix<T, N, M>::size() const
00118 {
00119 return Dim;
00120 }
00121
00122 #ifdef SGE_HAVE_VARIADIC_TEMPLATES
00123 template<typename T, std::size_t N, std::size_t M>
00124 template<typename... Args>
00125 void sge::math::basic_matrix<T, N, M>::set(
00126 const_reference arg,
00127 Args... args)
00128 {
00129 set_impl(0, arg, args...);
00130 }
00131
00132 template<typename T, std::size_t N, std::size_t M>
00133 template<typename... Args>
00134 void sge::math::basic_matrix<T, N, M>::set_impl(
00135 const size_type i,
00136 const_reference arg,
00137 Args... args)
00138 {
00139 at(i) = arg;
00140 set_impl(i+1, args...);
00141 }
00142
00143 template<typename T, std::size_t N, std::size_t M>
00144 void sge::math::basic_matrix<T, N, M>::set_impl(
00145 const size_type i,
00146 const_reference arg)
00147 {
00148 at(i) = arg;
00149 }
00150
00151 template<typename T, std::size_t N, std::size_t M>
00152 typename sge::math::basic_matrix<T, N, M>::reference
00153 sge::math::basic_matrix<T, N, M>::at(const size_type i)
00154 {
00155 if(i >= Dim)
00156 throw exception(SGE_TEXT("basic_matrix<T, N, M>::at(): out of range!"));
00157 return data_[i];
00158 }
00159 #endif
00160
00161 template<typename T, std::size_t N, std::size_t M>
00162 inline sge::math::basic_matrix<T,N,M> sge::math::operator+ (const basic_matrix<T,N,M>& r)
00163 {
00164 basic_matrix<T,N,M> ret;
00165 for(typename basic_matrix<T,N,M>::size_type i = 0; i < r.size(); ++i)
00166 ret.data_[i] = +ret.data_[i];
00167 return ret;
00168 }
00169
00170 template<typename T, std::size_t N, std::size_t M>
00171 inline sge::math::basic_matrix<T,N,M> sge::math::operator- (const basic_matrix<T,N,M>& r)
00172 {
00173 basic_matrix<T,N,M> ret;
00174 for(typename basic_matrix<T,N,M>::size_type i = 0; i < r.size(); ++i)
00175 ret.data_[i] = -ret.data_[i];
00176 return ret;
00177 }
00178
00179 template<typename T, std::size_t N, std::size_t M>
00180 inline sge::math::basic_matrix<T,N,M> sge::math::operator+ (const basic_matrix<T,N,M>& l, const basic_matrix<T,N,M>& r)
00181 {
00182 return basic_matrix<T,N,M>(l) += r;
00183 }
00184
00185 template<typename T, std::size_t N, std::size_t M>
00186 inline sge::math::basic_matrix<T,N,M> sge::math::operator- (const basic_matrix<T,N,M>& l, const basic_matrix<T,N,M>& r)
00187 {
00188 return basic_matrix<T,N,M>(l) -= r;
00189 }
00190
00191 template<typename T, std::size_t N, std::size_t M>
00192 inline sge::math::basic_matrix<T,N,M> sge::math::operator* (const typename basic_matrix<T,N,M>::value_type& l, const basic_matrix<T,N,M>& r)
00193 {
00194 return basic_matrix<T,N,M>(r) *= l;
00195 }
00196
00197 template<typename T, std::size_t N, std::size_t M1, std::size_t M2>
00198 inline sge::math::basic_matrix<T,N,N> sge::math::operator* (const basic_matrix<T,M1,N>& a, const basic_matrix<T,N,M2>& b)
00199 {
00200 typedef basic_matrix<T,M1,M2> result_type;
00201 result_type ret = result_type(no_initialization_tag());
00202 for(typename basic_matrix<T,M1,N>::size_type i = 0; i < M1; ++i)
00203 for(typename basic_matrix<T,N,M2>::size_type j = 0; j < M2; ++j)
00204 {
00205 typename result_type::value_type v(0);
00206 for(typename result_type::size_type r = 0; r < N; ++r)
00207 v += a[i][r] * b[r][j];
00208 ret[i][j] = v;
00209 }
00210 return ret;
00211 }
00212
00213 template<typename T, std::size_t N, std::size_t M>
00214 inline bool sge::math::operator== (const basic_matrix<T,N,M>& l, const basic_matrix<T,N,M>& r)
00215 {
00216 return std::equal(l.begin(), l.end(), r.begin(), std::ptr_fun(compare<T>));
00217 }
00218
00219 template<typename T, std::size_t N, std::size_t M>
00220 inline bool sge::math::operator!= (const basic_matrix<T,N,M>& l, const basic_matrix<T,N,M>& r)
00221 {
00222 return !(l==r);
00223 }
00224
00225 template<typename T, std::size_t N, std::size_t M,typename Ch, typename Traits>
00226 inline std::basic_ostream<Ch,Traits>& sge::math::operator<< (std::basic_ostream<Ch,Traits>& s, const basic_matrix<T,N,M>& m)
00227 {
00228 s << s.widen('(');
00229 for(typename basic_matrix<T,N,M>::size_type j = 0; j < N; ++j)
00230 {
00231 s << s.widen('(');
00232 for(typename basic_matrix<T,N,M>::size_type i = 0; i < M; ++i)
00233 {
00234 s << m[j][i];
00235 if(i != M-1)
00236 s << s.widen(',');
00237 }
00238 s << s.widen(')');
00239 if(j != N-1)
00240 s << s.widen(',');
00241 }
00242 return s << s.widen(')');
00243 }
00244
00245 template<typename T, std::size_t N>
00246 inline sge::math::basic_matrix<T,N,N> sge::math::transpose(const basic_matrix<T,N,N>& m)
00247 {
00248 basic_matrix<T,N,N> ret = basic_matrix<T,N,N>(no_initialization_tag());
00249 for(typename basic_matrix<T,N,N>::size_type j = 0; j < N; ++j)
00250 for(typename basic_matrix<T,N,N>::size_type i = 0; i < N; ++i)
00251 ret[i][j] = m[j][i];
00252 return ret;
00253 }
00254
00255 template<typename T, std::size_t N, std::size_t M>
00256 sge::math::basic_vector<T,M>
00257 sge::math::operator* (
00258 const basic_matrix<T,N,M>& m,
00259 const basic_vector<T,N>& v)
00260 {
00261 typedef basic_vector<T,M> result_type;
00262 result_type ret;
00263 for(typename result_type::size_type i = 0; i < M; ++i)
00264 for(typename basic_matrix<T,N,M>::size_type j = 0; j < N; ++j)
00265 ret[i] += v[j] * m[j][i];
00266 return ret;
00267 }
00268
00269 #endif