00001 #ifndef VIENNAMATH_MANIPULATION_COEFFICIENT_HPP
00002 #define VIENNAMATH_MANIPULATION_COEFFICIENT_HPP
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "viennamath/forwards.h"
00021 #include "viennamath/manipulation/expand.hpp"
00022
00027 namespace viennamath
00028 {
00030 namespace result_of
00031 {
00033 namespace detail
00034 {
00035
00036 template <typename FactorType,
00037 typename ExpressionType>
00038 struct coefficient_impl;
00039
00040
00041
00042
00043
00044 template <typename FactorType,
00045 typename ExpressionType>
00046 struct has_factor
00047 {
00048 enum { value = 0 };
00049 };
00050
00051 template <typename FactorType>
00052 struct has_factor<FactorType, FactorType>
00053 {
00054 enum { value = 1 };
00055 };
00056
00057 template <typename FactorType,
00058 typename LHS, typename NumericT, typename RHS>
00059 struct has_factor< FactorType, ct_binary_expr<LHS, op_plus<NumericT>, RHS> >
00060 {
00061 typedef typename ct_binary_expr<LHS, op_plus<NumericT>, RHS>::ERROR_EXPRESSION_NOT_FULLY_EXPANDED error_type;
00062 enum { value = 0 };
00063 };
00064
00065 template <typename FactorType,
00066 typename LHS, typename NumericT, typename RHS>
00067 struct has_factor< FactorType, ct_binary_expr<LHS, op_minus<NumericT>, RHS> >
00068 {
00069 typedef typename ct_binary_expr<LHS, op_minus<NumericT>, RHS>::ERROR_EXPRESSION_NOT_FULLY_EXPANDED error_type;
00070 enum { value = 0 };
00071 };
00072
00073 template <typename FactorType,
00074 typename LHS, typename NumericT, typename RHS>
00075 struct has_factor< FactorType, ct_binary_expr<LHS, op_mult<NumericT>, RHS> >
00076 {
00077 enum { value = has_factor<FactorType, LHS>::value + has_factor<FactorType, RHS>::value };
00078 };
00079
00080 template <typename FactorType,
00081 typename LHS, typename NumericT, typename RHS>
00082 struct has_factor< FactorType, ct_binary_expr<LHS, op_div<NumericT>, RHS> >
00083 {
00084 enum { value = has_factor<FactorType, LHS>::value };
00085 };
00086
00087
00088
00089
00090 template <typename FactorType,
00091 typename LHS, typename NumericT, typename RHS,
00092 bool lhs_has_factor = (has_factor<FactorType, LHS>::value != 0),
00093 bool rhs_has_factor = (has_factor<FactorType, RHS>::value != 0)
00094 >
00095 struct extract_factor_from_product
00096 {
00097
00098 typedef ct_constant<0> type;
00099 };
00100
00101 template <typename FactorType,
00102 typename LHS, typename NumericT, typename RHS>
00103 struct extract_factor_from_product<FactorType, LHS, NumericT, RHS, true, false>
00104 {
00105
00106 typedef ct_binary_expr< typename coefficient_impl<FactorType, LHS>::type,
00107 op_mult<NumericT>,
00108 RHS
00109 > type;
00110 };
00111
00112 template <typename FactorType,
00113 typename LHS, typename NumericT, typename RHS>
00114 struct extract_factor_from_product<FactorType, LHS, NumericT, RHS, false, true>
00115 {
00116
00117 typedef ct_binary_expr< LHS,
00118 op_mult<NumericT>,
00119 typename coefficient_impl<FactorType, RHS>::type
00120 > type;
00121 };
00122
00123 template <typename FactorType,
00124 typename LHS, typename NumericT, typename RHS>
00125 struct extract_factor_from_product<FactorType, LHS, NumericT, RHS, true, true>
00126 {
00127
00128 typedef ct_binary_expr< typename coefficient_impl<FactorType, LHS>::type,
00129 op_mult<NumericT>,
00130 RHS
00131 > type;
00132 };
00133
00134
00135
00136
00137 template <typename FactorType,
00138 typename ExpressionType>
00139 struct coefficient_impl
00140 {
00141 typedef ct_constant<0> type;
00142 };
00143
00144 template <typename FactorType>
00145 struct coefficient_impl<FactorType, FactorType>
00146 {
00147 typedef ct_constant<1> type;
00148 };
00149
00150 template <typename FactorType,
00151 typename LHS, typename NumericT, typename RHS>
00152 struct coefficient_impl< FactorType, ct_binary_expr<LHS, op_plus<NumericT>, RHS> >
00153 {
00154 typedef ct_binary_expr< typename coefficient_impl<FactorType, LHS>::type,
00155 op_plus<NumericT>,
00156 typename coefficient_impl<FactorType, RHS>::type
00157 > type;
00158 };
00159
00160 template <typename FactorType,
00161 typename LHS, typename NumericT, typename RHS>
00162 struct coefficient_impl< FactorType, ct_binary_expr<LHS, op_minus<NumericT>, RHS> >
00163 {
00164 typedef ct_binary_expr< typename coefficient_impl<FactorType, LHS>::type,
00165 op_minus<NumericT>,
00166 typename coefficient_impl<FactorType, RHS>::type
00167 > type;
00168 };
00169
00170 template <typename FactorType,
00171 typename LHS, typename NumericT, typename RHS>
00172 struct coefficient_impl< FactorType, ct_binary_expr<LHS, op_mult<NumericT>, RHS> >
00173 {
00174 typedef typename extract_factor_from_product<FactorType, LHS, NumericT, RHS>::type type;
00175 };
00176
00177 template <typename FactorType,
00178 typename NumericT, typename RHS>
00179 struct coefficient_impl< FactorType, ct_binary_expr<FactorType, op_mult<NumericT>, RHS> >
00180 {
00181 typedef RHS type;
00182 };
00183
00184 template <typename FactorType,
00185 typename LHS, typename NumericT>
00186 struct coefficient_impl< FactorType, ct_binary_expr<LHS, op_mult<NumericT>, FactorType> >
00187 {
00188 typedef LHS type;
00189 };
00190
00191 template <typename FactorType,
00192 typename NumericT>
00193 struct coefficient_impl< FactorType, ct_binary_expr<FactorType, op_mult<NumericT>, FactorType> >
00194 {
00195 typedef FactorType type;
00196 };
00197
00198 template <typename FactorType,
00199 typename LHS, typename NumericT, typename RHS>
00200 struct coefficient_impl< FactorType, ct_binary_expr<LHS, op_div<NumericT>, RHS> >
00201 {
00202 typedef ct_binary_expr< typename coefficient_impl<FactorType, LHS>::type,
00203 op_div<NumericT>,
00204 RHS
00205 > type;
00206 };
00207
00208 }
00209
00210
00211
00217 template <typename FactorType,
00218 typename ExpressionType>
00219 struct coefficient
00220 {
00221 typedef typename viennamath::result_of::expand<ExpressionType>::type expanded_expression;
00222
00223 typedef typename detail::coefficient_impl<FactorType, expanded_expression>::type type;
00224 };
00225 }
00226
00227
00228
00234 template <typename FactorType,
00235 typename ExpressionType>
00236 typename viennamath::result_of::coefficient<FactorType, ExpressionType>::type
00237 coefficient(FactorType const & f, ExpressionType const & e)
00238 {
00239 return typename viennamath::result_of::coefficient<FactorType, ExpressionType>::type();
00240 }
00241
00242
00243
00244
00245
00247
00248
00249
00250 }
00251
00252 #endif