00001 #ifndef VIENNAMATH_MANIPULATION_DIFF_HPP
00002 #define VIENNAMATH_MANIPULATION_DIFF_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/runtime/unary_expr.hpp"
00022 #include "viennamath/manipulation/simplify.hpp"
00023
00028 namespace viennamath
00029 {
00030
00032
00033
00039 template <typename InterfaceType>
00040 rt_expr<InterfaceType> diff(rt_binary_expr<InterfaceType> const & e,
00041 rt_variable<InterfaceType> const & var)
00042 {
00043 rt_expr<InterfaceType> temp(e.diff(&var));
00044 inplace_simplify(temp);
00045 return temp;
00046 }
00047
00053 template <typename InterfaceType>
00054 rt_expr<InterfaceType> diff(rt_unary_expr<InterfaceType> const & e,
00055 rt_variable<InterfaceType> const & var)
00056 {
00057 rt_expr<InterfaceType> temp(e.diff(&var));
00058 inplace_simplify(temp);
00059 return temp;
00060 }
00061
00067 template <typename InterfaceType>
00068 rt_expr<InterfaceType> diff(rt_expr<InterfaceType> const & e,
00069 rt_variable<InterfaceType> const & var)
00070 {
00071 rt_expr<InterfaceType> temp(e.get()->diff(&var));
00072 inplace_simplify(temp);
00073 return temp;
00074 }
00075
00076
00082 template <typename InterfaceType, id_type id>
00083 rt_expr<InterfaceType> diff(rt_binary_expr<InterfaceType> const & e,
00084 ct_variable<id> const & var)
00085 {
00086 rt_variable<InterfaceType> temp(id);
00087 return diff(e, temp);
00088 }
00089
00095 template <typename InterfaceType, id_type id>
00096 rt_expr<InterfaceType> diff(rt_unary_expr<InterfaceType> const & e,
00097 ct_variable<id> const & var)
00098 {
00099 rt_variable<InterfaceType> temp(id);
00100 return diff(e, temp);
00101 }
00102
00108 template <typename InterfaceType, id_type id>
00109 rt_expr<InterfaceType> diff(rt_expr<InterfaceType> const & e,
00110 ct_variable<id> const & var)
00111 {
00112 rt_variable<InterfaceType> temp(id);
00113 return diff(e, temp);
00114 }
00115
00116
00117
00118
00119
00121 template <typename InterfaceType>
00122 rt_expr<InterfaceType> diff(rt_function_symbol<InterfaceType> const & other,
00123 rt_variable<InterfaceType> const & var)
00124 {
00125 typedef op_partial_deriv<typename InterfaceType::numeric_type> d_dx_type;
00126 return rt_expr<InterfaceType>(new rt_unary_expr<InterfaceType>(other.clone(),
00127 new op_unary<d_dx_type, InterfaceType>(d_dx_type(var.id()))
00128 )
00129 );
00130 }
00131
00133 template <typename InterfaceType, id_type id>
00134 rt_expr<InterfaceType> diff(rt_function_symbol<InterfaceType> const & other,
00135 ct_variable<id> const & var)
00136 {
00137 typedef op_partial_deriv<typename InterfaceType::numeric_type> d_dx_type;
00138 return rt_expr<InterfaceType>(new rt_unary_expr<InterfaceType>(other.clone(),
00139 new op_unary<d_dx_type, InterfaceType>(d_dx_type(id))
00140 )
00141 );
00142 }
00143
00145
00147 template <typename InterfaceType>
00148 rt_constant<typename InterfaceType::numeric_type> diff(typename InterfaceType::numeric_type value,
00149 rt_variable<InterfaceType> const & var)
00150 {
00151 return rt_constant<typename InterfaceType::numeric_type>(0);
00152 }
00153
00155 template <typename OtherScalarType, typename InterfaceType>
00156 rt_constant<typename InterfaceType::numeric_type> diff(rt_constant<OtherScalarType, InterfaceType> const & c,
00157 rt_variable<InterfaceType> const & var)
00158 {
00159 return rt_constant<typename InterfaceType::numeric_type>(0);
00160 }
00161
00163
00165 template <id_type other_id, typename InterfaceType,
00166 id_type id>
00167 rt_constant<typename InterfaceType::numeric_type> diff(rt_variable<InterfaceType> const & c,
00168 rt_variable<InterfaceType> const & var)
00169 {
00170 if (c.id() == var.id())
00171 return rt_constant<typename InterfaceType::numeric_type>(1);
00172
00173 return rt_constant<typename InterfaceType::numeric_type>(0);
00174 }
00175
00176
00177
00179
00180
00181
00182
00183 namespace result_of
00184 {
00185
00191 template <typename ARG, typename VAR>
00192 struct diff {};
00193
00194
00195
00196
00197
00199 template <typename LHS, typename RHS, id_type id>
00200 struct diff<ct_binary_expr<LHS, op_plus<default_numeric_type>, RHS>,
00201 ct_variable<id> >
00202 {
00203 typedef ct_binary_expr< typename diff<LHS, ct_variable<id> >::result_type,
00204 op_plus<default_numeric_type>,
00205 typename diff<RHS, ct_variable<id> >::result_type > result_type;
00206 };
00207
00209 template <typename LHS, typename RHS, id_type id>
00210 struct diff<ct_binary_expr<LHS, op_minus<default_numeric_type>, RHS>,
00211 ct_variable<id> >
00212 {
00213 typedef ct_binary_expr< typename diff<LHS, ct_variable<id> >::result_type,
00214 op_minus<default_numeric_type>,
00215 typename diff<RHS, ct_variable<id> >::result_type > result_type;
00216 };
00217
00219 template <typename LHS, typename RHS, id_type id>
00220 struct diff<ct_binary_expr<LHS, op_mult<default_numeric_type>, RHS>,
00221 ct_variable<id> >
00222 {
00223 typedef ct_binary_expr< ct_binary_expr< typename diff<LHS, ct_variable<id> >::result_type,
00224 op_mult<default_numeric_type>,
00225 RHS>,
00226 op_plus<default_numeric_type>,
00227 ct_binary_expr< LHS,
00228 op_mult<default_numeric_type>,
00229 typename diff<RHS, ct_variable<id> >::result_type >
00230 > result_type;
00231 };
00232
00234 template <typename LHS, typename RHS, id_type id>
00235 struct diff<ct_binary_expr<LHS, op_div<default_numeric_type>, RHS>,
00236 ct_variable<id> >
00237 {
00238 typedef ct_binary_expr< ct_binary_expr< ct_binary_expr< typename diff<LHS, ct_variable<id> >::result_type,
00239 op_mult<default_numeric_type>,
00240 RHS>,
00241 op_minus<default_numeric_type>,
00242 ct_binary_expr< LHS,
00243 op_mult<default_numeric_type>,
00244 typename diff<RHS, ct_variable<id> >::result_type >
00245 >,
00246 op_div<default_numeric_type>,
00247 ct_binary_expr< RHS,
00248 op_mult<default_numeric_type>,
00249 RHS >
00250 > result_type;
00251 };
00252
00254 template <id_type other_id,
00255 id_type id>
00256 struct diff< ct_variable<other_id>,
00257 ct_variable<id> >
00258 {
00259 typedef ct_constant<0> result_type;
00260 };
00261
00263 template <id_type id>
00264 struct diff< ct_variable<id>,
00265 ct_variable<id> >
00266 {
00267 typedef ct_constant<1> result_type;
00268 };
00269
00271 template <long value, id_type id>
00272 struct diff< ct_constant<value>,
00273 ct_variable<id> >
00274 {
00275 typedef ct_constant<0> result_type;
00276 };
00277
00278 }
00279
00280
00281
00282
00283
00285 template <typename ExpressionType,
00286 id_type id>
00287 typename result_of::diff<ExpressionType,
00288 ct_variable<id> >::result_type
00289 diff(ExpressionType const & c,
00290 ct_variable<id> const & var)
00291 {
00292 return typename result_of::diff<ExpressionType,
00293 ct_variable<id> >::result_type();
00294 }
00295
00296
00297
00298 }
00299
00300 #endif