00001
00002
00003
00004
00005
00006
00007
00008
00023 #ifndef matvec_mul_h
00024 #define matvec_mul_h
00025
00026 #include <cml/core/cml_meta.h>
00027 #include <cml/vector/vector_expr.h>
00028 #include <cml/matrix/matrix_expr.h>
00029 #include <cml/matvec/matvec_promotions.h>
00030
00031
00032
00033
00034 struct mvmul_expects_one_matrix_and_one_vector_arg_error;
00035 struct mvmul_expects_one_vector_and_one_matrix_arg_error;
00036
00037 namespace cml {
00038 namespace detail {
00039
00040
00041 typedef true_type mul_Ax;
00042 typedef false_type mul_xA;
00043
00045 template<typename LeftT, typename RightT> inline
00046 typename et::MatVecPromote<
00047 typename et::ExprTraits<LeftT>::result_type,
00048 typename et::ExprTraits<RightT>::result_type
00049 >::temporary_type
00050 mul(const LeftT& A, const RightT& x, mul_Ax)
00051 {
00052
00053 typedef et::ExprTraits<LeftT> left_traits;
00054 typedef et::ExprTraits<RightT> right_traits;
00055 typedef typename left_traits::result_tag left_result;
00056 typedef typename right_traits::result_tag right_result;
00057
00058
00059 CML_STATIC_REQUIRE_M(
00060 (same_type<left_result, et::matrix_result_tag>::is_true
00061 && same_type<right_result, et::vector_result_tag>::is_true),
00062 mvmul_expects_one_matrix_and_one_vector_arg_error);
00063
00064
00065
00066
00067
00068 typedef typename et::MatVecPromote<
00069 typename left_traits::result_type,
00070 typename right_traits::result_type
00071 >::temporary_type result_type;
00072
00073
00074 typedef typename result_type::size_tag size_tag;
00075
00076
00077 size_t N = et::CheckedSize(A, x, size_tag());
00078
00079
00080 result_type y; cml::et::detail::Resize(y, N);
00081
00082
00083 typedef typename result_type::value_type sum_type;
00084 for(size_t i = 0; i < N; ++i) {
00085
00086 sum_type sum(A(i,0)*x[0]);
00087 for(size_t k = 1; k < x.size(); ++k) {
00088 sum += (A(i,k)*x[k]);
00089 }
00090 y[i] = sum;
00091 }
00092
00093 return y;
00094 }
00095
00097 template<typename LeftT, typename RightT> inline
00098 typename et::MatVecPromote<
00099 typename et::ExprTraits<LeftT>::result_type,
00100 typename et::ExprTraits<RightT>::result_type
00101 >::temporary_type
00102 mul(const LeftT& x, const RightT& A, mul_xA)
00103 {
00104
00105 typedef et::ExprTraits<LeftT> left_traits;
00106 typedef et::ExprTraits<RightT> right_traits;
00107 typedef typename left_traits::result_tag left_result;
00108 typedef typename right_traits::result_tag right_result;
00109
00110
00111 CML_STATIC_REQUIRE_M(
00112 (same_type<left_result, et::vector_result_tag>::is_true
00113 && same_type<right_result, et::matrix_result_tag>::is_true),
00114 mvmul_expects_one_vector_and_one_matrix_arg_error);
00115
00116
00117
00118
00119
00120 typedef typename et::MatVecPromote<
00121 typename left_traits::result_type,
00122 typename right_traits::result_type
00123 >::temporary_type result_type;
00124
00125
00126 typedef typename result_type::size_tag size_tag;
00127
00128
00129 size_t N = et::CheckedSize(x, A, size_tag());
00130
00131
00132 result_type y; cml::et::detail::Resize(y, N);
00133
00134
00135 typedef typename result_type::value_type sum_type;
00136 for(size_t i = 0; i < N; ++i) {
00137
00138 sum_type sum(x[0]*A(0,i));
00139 for(size_t k = 1; k < x.size(); ++k) {
00140 sum += (x[k]*A(k,i));
00141 }
00142 y[i] = sum;
00143 }
00144
00145 return y;
00146 }
00147
00148 }
00149
00150
00152 template<typename E1, class AT1, typename BO, class L,
00153 typename E2, class AT2>
00154 inline typename et::MatVecPromote<
00155 matrix<E1,AT1,BO,L>, vector<E2,AT2>
00156 >::temporary_type
00157 operator*(const matrix<E1,AT1,BO,L>& left,
00158 const vector<E2,AT2>& right)
00159 {
00160 return detail::mul(left,right,detail::mul_Ax());
00161 }
00162
00164 template<typename E, class AT, class L, typename BO, typename XprT>
00165 inline typename et::MatVecPromote<
00166 matrix<E,AT,BO,L>, typename XprT::result_type
00167 >::temporary_type
00168 operator*(const matrix<E,AT,BO,L>& left,
00169 const et::VectorXpr<XprT>& right)
00170 {
00171
00172 typename et::VectorXpr<XprT>::temporary_type right_tmp;
00173 cml::et::detail::Resize(right_tmp,right.size());
00174 right_tmp = right;
00175
00176 return detail::mul(left,right_tmp,detail::mul_Ax());
00177 }
00178
00180 template<typename XprT, typename E, class AT>
00181 inline typename et::MatVecPromote<
00182 typename XprT::result_type, vector<E,AT>
00183 >::temporary_type
00184 operator*(const et::MatrixXpr<XprT>& left,
00185 const vector<E,AT>& right)
00186 {
00187
00188 typename et::MatrixXpr<XprT>::temporary_type left_tmp;
00189 cml::et::detail::Resize(left_tmp,left.rows(),left.cols());
00190 left_tmp = left;
00191
00192 return detail::mul(left_tmp,right,detail::mul_Ax());
00193 }
00194
00196 template<typename XprT1, typename XprT2>
00197 inline typename et::MatVecPromote<
00198 typename XprT1::result_type, typename XprT2::result_type
00199 >::temporary_type
00200 operator*(const et::MatrixXpr<XprT1>& left,
00201 const et::VectorXpr<XprT2>& right)
00202 {
00203
00204 typename et::MatrixXpr<XprT1>::temporary_type left_tmp;
00205 cml::et::detail::Resize(left_tmp,left.rows(),left.cols());
00206 left_tmp = left;
00207
00208
00209 typename et::VectorXpr<XprT2>::temporary_type right_tmp;
00210 cml::et::detail::Resize(right_tmp,right.size());
00211 right_tmp = right;
00212
00213 return detail::mul(left_tmp,right_tmp,detail::mul_Ax());
00214 }
00215
00217 template<typename E1, class AT1, typename E2, class AT2, typename BO, class L>
00218 inline typename et::MatVecPromote<
00219 vector<E1,AT1>, matrix<E2,AT2,BO,L>
00220 >::temporary_type
00221 operator*(const vector<E1,AT1>& left,
00222 const matrix<E2,AT2,BO,L>& right)
00223 {
00224 return detail::mul(left,right,detail::mul_xA());
00225 }
00226
00228 template<typename XprT, typename E, class AT>
00229 inline typename et::MatVecPromote<
00230 typename XprT::result_type, vector<E,AT>
00231 >::temporary_type
00232 operator*(const vector<E,AT>& left,
00233 const et::MatrixXpr<XprT>& right)
00234 {
00235
00236 typename et::MatrixXpr<XprT>::temporary_type right_tmp;
00237 cml::et::detail::Resize(right_tmp,right.rows(),right.cols());
00238 right_tmp = right;
00239
00240 return detail::mul(left,right_tmp,detail::mul_xA());
00241 }
00242
00244 template<typename XprT, typename E, class AT, typename BO, class L>
00245 inline typename et::MatVecPromote<
00246 typename XprT::result_type, matrix<E,AT,BO,L>
00247 >::temporary_type
00248 operator*(const et::VectorXpr<XprT>& left,
00249 const matrix<E,AT,BO,L>& right)
00250 {
00251
00252 typename et::VectorXpr<XprT>::temporary_type left_tmp;
00253 cml::et::detail::Resize(left_tmp,left.size());
00254 left_tmp = left;
00255
00256 return detail::mul(left_tmp,right,detail::mul_xA());
00257 }
00258
00260 template<typename XprT1, typename XprT2>
00261 inline typename et::MatVecPromote<
00262 typename XprT1::result_type, typename XprT2::result_type
00263 >::temporary_type
00264 operator*(const et::VectorXpr<XprT1>& left,
00265 const et::MatrixXpr<XprT2>& right)
00266 {
00267
00268 typename et::VectorXpr<XprT1>::temporary_type left_tmp;
00269 cml::et::detail::Resize(left_tmp,left.size());
00270 left_tmp = left;
00271
00272
00273 typename et::MatrixXpr<XprT2>::temporary_type right_tmp;
00274 cml::et::detail::Resize(right_tmp,right.rows(),right.cols());
00275 right_tmp = right;
00276
00277 return detail::mul(left_tmp,right_tmp,detail::mul_xA());
00278 }
00279
00280 }
00281
00282 #endif
00283
00284
00285