00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef MTL_MAT_MAT_TIMES_EXPR_INCLUDE
00013 #define MTL_MAT_MAT_TIMES_EXPR_INCLUDE
00014
00015 #include <boost/mpl/if.hpp>
00016 #include <boost/mpl/and.hpp>
00017 #include <boost/shared_ptr.hpp>
00018 #include <boost/type_traits.hpp>
00019
00020 #include <boost/numeric/mtl/mtl_fwd.hpp>
00021 #include <boost/numeric/mtl/matrix/mat_mat_op_expr.hpp>
00022 #include <boost/numeric/mtl/operation/sfunctor.hpp>
00023 #include <boost/numeric/mtl/operation/compute_factors.hpp>
00024 #include <boost/numeric/linear_algebra/identity.hpp>
00025 #include <boost/numeric/mtl/matrix/parameter.hpp>
00026 #include <boost/numeric/mtl/matrix/dense2D.hpp>
00027 #include <boost/numeric/mtl/matrix/compressed2D.hpp>
00028 #include <boost/numeric/mtl/concept/std_concept.hpp>
00029 #include <boost/numeric/mtl/concept/collection.hpp>
00030 #include <boost/numeric/mtl/utility/category.hpp>
00031 #include <boost/numeric/mtl/utility/tag.hpp>
00032
00033
00034 namespace mtl { namespace matrix {
00035
00036 template <typename E1, typename E2>
00037 struct mat_mat_times_expr
00038 : public mat_mat_op_expr< E1, E2, mtl::sfunctor::times<typename E1::value_type, typename E2::value_type> >,
00039 public mat_expr< mat_mat_times_expr<E1, E2> >
00040 {
00041 typedef mat_mat_op_expr< E1, E2, mtl::sfunctor::times<typename E1::value_type, typename E2::value_type> > op_base;
00042 typedef mat_expr< mat_mat_times_expr<E1, E2> > crtp_base;
00043 typedef mat_mat_times_expr self;
00044 typedef E1 first_argument_type ;
00045 typedef E2 second_argument_type ;
00046 typedef typename E1::orientation orientation;
00047 typedef mtl::non_fixed::dimensions dim_type;
00048 typedef typename E1::key_type key_type;
00049
00050 #if 0 // TODO: Doesn't find first_argument_type due to some const qualification or alike
00051 typedef typename Collection<E1>::value_type first_value_type;
00052 typedef typename Collection<E2>::value_type second_value_type;
00053 #else
00054 typedef typename E1::value_type first_value_type;
00055 typedef typename E2::value_type second_value_type;
00056 #endif
00057 typedef typename Multiplicable<first_value_type, second_value_type>::result_type result_value_type;
00058
00059 #if 0 // Just an idea
00060 typedef typename boost::mpl::if_<
00061 boost::mpl::and_<
00062 boost::is_base_of<tag::sparse, typename traits::category<E1>::type>
00063 , boost::is_base_of<tag::sparse, typename traits::category<E2>::type>
00064 >
00065 , compressed2D<result_value_type>
00066 , dense2D<result_value_type, parameters<> >
00067 >::type evaluated_result_type;
00068
00069
00070
00071 operator evaluated_result_type() const
00072 {
00073 return evaluated_result_type(first * second);
00074 }
00075 #endif
00076
00077 mat_mat_times_expr( E1 const& v1, E2 const& v2 )
00078 : op_base( v1, v2 ), crtp_base(*this), first(v1), second(v2)
00079 {}
00080
00081
00082
00083
00084
00085
00086 result_value_type
00087 operator()(std::size_t r, std::size_t c) const
00088 {
00089 using math::zero;
00090 MTL_THROW_IF(num_cols(first) != num_rows(second), incompatible_size());
00091
00092 result_value_type ref, sum(zero(ref));
00093 for (std::size_t i= 0; i < num_cols(first); i++)
00094 sum+= first(r, i) * second(i, c);
00095 return sum;
00096 }
00097
00098
00099 result_value_type
00100 operator()(std::size_t r, std::size_t c)
00101 {
00102 return (*const_cast<const self*>(this))(r, c);
00103 }
00104
00105 first_argument_type const& first ;
00106 second_argument_type const& second ;
00107 };
00108
00109 template <typename E1, typename E2>
00110 std::size_t inline num_rows(const mat_mat_times_expr<E1, E2>& expr)
00111 { return num_rows(expr.first); }
00112
00113 template <typename E1, typename E2>
00114 std::size_t inline num_cols(const mat_mat_times_expr<E1, E2>& expr)
00115 { return num_cols(expr.second); }
00116
00117 template <typename E1, typename E2>
00118 std::size_t inline size(const mat_mat_times_expr<E1, E2>& expr)
00119 { return num_rows(expr) * num_cols(expr); }
00120
00121 }}
00122
00123 #endif // MTL_MAT_MAT_TIMES_EXPR_INCLUDE