00001 #ifndef VIENNAMATH_UNARY_OPERATORS_MANIPULATION_HPP
00002 #define VIENNAMATH_UNARY_OPERATORS_MANIPULATION_HPP
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <string>
00021 #include <vector>
00022 #include <math.h>
00023 #include "viennamath/forwards.h"
00024 #include "viennamath/exception.hpp"
00025 #include "viennamath/compiletime/unary_op_tags.hpp"
00026 #include "viennamath/runtime/unary_expr.hpp"
00027 #include "viennamath/runtime/binary_expr.hpp"
00028 #include "viennamath/runtime/integral.hpp"
00029
00034 namespace viennamath
00035 {
00036
00037
00038
00039
00041 template <typename InterfaceType, typename NumericT>
00042 InterfaceType * diff_impl(const InterfaceType * e, op_id<NumericT>, const InterfaceType * diff_var)
00043 {
00044 return e->diff(diff_var);
00045 }
00046
00047
00048
00049
00051 template <typename InterfaceType, typename NumericT>
00052 InterfaceType * diff_impl(const InterfaceType * e, op_exp<NumericT>, const InterfaceType * diff_var)
00053 {
00054 return new rt_binary_expr<InterfaceType>( new rt_unary_expr<InterfaceType>(e->clone(), new op_unary<op_exp<NumericT>, InterfaceType>()),
00055 new op_binary<op_mult<typename InterfaceType::numeric_type>, InterfaceType>(),
00056 e->diff(diff_var));
00057 }
00058
00060 template <typename NumericT, typename InterfaceType>
00061 rt_unary_expr<InterfaceType> exp(rt_constant<NumericT, InterfaceType> const & other)
00062 {
00063 return rt_unary_expr<InterfaceType>(other.clone(), new op_unary<op_exp<typename InterfaceType::numeric_type>, InterfaceType>());
00064 }
00065
00067 template <typename InterfaceType>
00068 rt_unary_expr<InterfaceType> exp(rt_variable<InterfaceType> const & other)
00069 {
00070 return rt_unary_expr<InterfaceType>(other.clone(), new op_unary<op_exp<typename InterfaceType::numeric_type>, InterfaceType>());
00071 }
00072
00074 template <id_type id>
00075 rt_unary_expr<> exp(ct_variable<id> const & other)
00076 {
00077 return rt_unary_expr<>(new rt_variable<>(id), new op_unary<op_exp<default_numeric_type> >());
00078 }
00079
00081 template <typename InterfaceType>
00082 rt_unary_expr<InterfaceType> exp(rt_binary_expr<InterfaceType> const & other)
00083 {
00084 return rt_unary_expr<InterfaceType>(other.clone(), new op_unary<op_exp<typename InterfaceType::numeric_type>, InterfaceType>());
00085 }
00086
00088 template <typename LHS, typename OP, typename RHS>
00089 rt_unary_expr<> exp(ct_binary_expr<LHS, OP, RHS> const & other)
00090 {
00091 return rt_unary_expr<>(new rt_binary_expr<>(other),
00092 new op_unary<op_exp<default_numeric_type> >());
00093 }
00094
00096 template <typename LHS, typename OP>
00097 rt_unary_expr<> exp(ct_unary_expr<LHS, OP> const & other)
00098 {
00099 return rt_unary_expr<>(new rt_unary_expr<>(other),
00100 new op_unary<op_exp<default_numeric_type> >());
00101 }
00102
00104 template <typename InterfaceType>
00105 rt_unary_expr<InterfaceType> exp(rt_expr<InterfaceType> const & other)
00106 {
00107 return rt_unary_expr<InterfaceType>(other.get()->clone(), new op_unary<op_exp<typename InterfaceType::numeric_type>, InterfaceType>());
00108 }
00109
00110
00111
00112
00113
00114
00116 template <typename InterfaceType, typename NumericT>
00117 InterfaceType * diff_impl(const InterfaceType * e, op_sin<NumericT>, const InterfaceType * diff_var)
00118 {
00119 return new rt_binary_expr<InterfaceType>( new rt_unary_expr<InterfaceType>(e->clone(), new op_unary<op_cos<NumericT>, InterfaceType>()),
00120 new op_binary<op_mult<typename InterfaceType::numeric_type>, InterfaceType>(),
00121 e->diff(diff_var) );
00122 }
00123
00125 template <typename NumericT, typename InterfaceType>
00126 rt_unary_expr<InterfaceType> sin(rt_constant<NumericT, InterfaceType> const & other)
00127 {
00128 return rt_unary_expr<InterfaceType>(other.clone(), new op_unary<op_sin<typename InterfaceType::numeric_type>, InterfaceType>());
00129 }
00130
00132 template <typename InterfaceType>
00133 rt_unary_expr<InterfaceType> sin(rt_variable<InterfaceType> const & other)
00134 {
00135 return rt_unary_expr<InterfaceType>(other.clone(), new op_unary<op_sin<typename InterfaceType::numeric_type>, InterfaceType>());
00136 }
00137
00139 template <id_type id>
00140 rt_unary_expr<> sin(ct_variable<id> const & other)
00141 {
00142 return rt_unary_expr<>(new rt_variable<>(id), new op_unary<op_sin<default_numeric_type> >());
00143 }
00144
00146 template <typename LHS, typename OP, typename RHS>
00147 rt_unary_expr<> sin(ct_binary_expr<LHS, OP, RHS> const & other)
00148 {
00149 return rt_unary_expr<>(new rt_binary_expr<>(other),
00150 new op_unary<op_sin<default_numeric_type> >());
00151 }
00152
00154 template <typename LHS, typename OP>
00155 rt_unary_expr<> sin(ct_unary_expr<LHS, OP> const & other)
00156 {
00157 return rt_unary_expr<>(new rt_unary_expr<>(other),
00158 new op_unary<op_sin<default_numeric_type> >());
00159 }
00160
00161
00163 template <typename InterfaceType>
00164 rt_unary_expr<InterfaceType> sin(rt_unary_expr<InterfaceType> const & other)
00165 {
00166 return rt_unary_expr<InterfaceType>(other.clone(), new op_unary<op_sin<typename InterfaceType::numeric_type>, InterfaceType>());
00167 }
00168
00170 template <typename InterfaceType>
00171 rt_unary_expr<InterfaceType> sin(rt_binary_expr<InterfaceType> const & other)
00172 {
00173 return rt_unary_expr<InterfaceType>(other.clone(), new op_unary<op_sin<typename InterfaceType::numeric_type>, InterfaceType>());
00174 }
00175
00177 template <typename InterfaceType>
00178 rt_unary_expr<InterfaceType> sin(rt_expr<InterfaceType> const & other)
00179 {
00180 return rt_unary_expr<InterfaceType>(other.get()->clone(), new op_unary<op_sin<typename InterfaceType::numeric_type>, InterfaceType>());
00181 }
00182
00183
00184
00185
00186
00187
00189 template <typename InterfaceType, typename NumericT>
00190 InterfaceType * diff_impl(const InterfaceType * e, op_cos<NumericT>, const InterfaceType * diff_var)
00191 {
00192 return new rt_binary_expr<InterfaceType>( new rt_unary_expr<InterfaceType>(e->clone(), new op_unary<op_sin<NumericT>, InterfaceType>()),
00193 new op_binary<op_mult<typename InterfaceType::numeric_type>, InterfaceType>(),
00194 new rt_binary_expr<InterfaceType>( new rt_constant<NumericT, InterfaceType>(-1),
00195 new op_binary<op_mult<typename InterfaceType::numeric_type>, InterfaceType>(),
00196 e->diff(diff_var) )
00197 );
00198 }
00199
00201 template <typename NumericT, typename InterfaceType>
00202 rt_unary_expr<InterfaceType> cos(rt_constant<NumericT, InterfaceType> const & other)
00203 {
00204 return rt_unary_expr<InterfaceType>(other.clone(), new op_unary<op_cos<typename InterfaceType::numeric_type>, InterfaceType>());
00205 }
00206
00208 template <typename InterfaceType>
00209 rt_unary_expr<InterfaceType> cos(rt_variable<InterfaceType> const & other)
00210 {
00211 return rt_unary_expr<InterfaceType>(other.clone(), new op_unary<op_cos<typename InterfaceType::numeric_type>, InterfaceType>());
00212 }
00213
00215 template <id_type id>
00216 rt_unary_expr<> cos(ct_variable<id> const & other)
00217 {
00218 return rt_unary_expr<>(new rt_variable<>(id), new op_unary<op_cos<default_numeric_type> >());
00219 }
00220
00222 template <typename LHS, typename OP, typename RHS>
00223 rt_unary_expr<> cos(ct_binary_expr<LHS, OP, RHS> const & other)
00224 {
00225 return rt_unary_expr<>(new rt_binary_expr<>(other),
00226 new op_unary<op_cos<default_numeric_type> >());
00227 }
00228
00230 template <typename LHS, typename OP>
00231 rt_unary_expr<> cos(ct_unary_expr<LHS, OP> const & other)
00232 {
00233 return rt_unary_expr<>(new rt_unary_expr<>(other),
00234 new op_unary<op_cos<default_numeric_type> >());
00235 }
00236
00237
00239 template <typename InterfaceType>
00240 rt_unary_expr<InterfaceType> cos(rt_unary_expr<InterfaceType> const & other)
00241 {
00242 return rt_unary_expr<InterfaceType>(other.clone(), new op_unary<op_cos<typename InterfaceType::numeric_type>, InterfaceType>());
00243 }
00244
00246 template <typename InterfaceType>
00247 rt_unary_expr<InterfaceType> cos(rt_binary_expr<InterfaceType> const & other)
00248 {
00249 return rt_unary_expr<InterfaceType>(other.clone(), new op_unary<op_cos<typename InterfaceType::numeric_type>, InterfaceType>());
00250 }
00251
00253 template <typename InterfaceType>
00254 rt_unary_expr<InterfaceType> cos(rt_expr<InterfaceType> const & other)
00255 {
00256 return rt_unary_expr<InterfaceType>(other.get()->clone(), new op_unary<op_cos<typename InterfaceType::numeric_type>, InterfaceType>());
00257 }
00258
00259
00260
00261
00263 template <typename InterfaceType, typename NumericT>
00264 InterfaceType * diff_impl(const InterfaceType * e, op_tan<NumericT>, const InterfaceType * diff_var)
00265 {
00266
00267 return new rt_binary_expr<InterfaceType>( e->diff(diff_var),
00268 new op_binary<op_div<typename InterfaceType::numeric_type>, InterfaceType>(),
00269 new rt_binary_expr<InterfaceType>( new rt_unary_expr<InterfaceType>(e->clone(),
00270 new op_unary<op_cos<NumericT>, InterfaceType>()),
00271 new op_binary<op_mult<typename InterfaceType::numeric_type>, InterfaceType>(),
00272 new rt_unary_expr<InterfaceType>(e->clone(),
00273 new op_unary<op_cos<NumericT>, InterfaceType>()) )
00274 );
00275 }
00276
00278 template <typename NumericT, typename InterfaceType>
00279 rt_unary_expr<InterfaceType> tan(rt_constant<NumericT, InterfaceType> const & other)
00280 {
00281 return rt_unary_expr<InterfaceType>(other.clone(), new op_unary<op_tan<typename InterfaceType::numeric_type>, InterfaceType>());
00282 }
00283
00285 template <typename InterfaceType>
00286 rt_unary_expr<InterfaceType> tan(rt_variable<InterfaceType> const & other)
00287 {
00288 return rt_unary_expr<InterfaceType>(other.clone(), new op_unary<op_tan<typename InterfaceType::numeric_type>, InterfaceType>());
00289 }
00290
00292 template <id_type id>
00293 rt_unary_expr<> tan(ct_variable<id> const & other)
00294 {
00295 return rt_unary_expr<>(new rt_variable<>(id), new op_unary<op_tan<default_numeric_type> >());
00296 }
00297
00299 template <typename LHS, typename OP, typename RHS>
00300 rt_unary_expr<> tan(ct_binary_expr<LHS, OP, RHS> const & other)
00301 {
00302 return rt_unary_expr<>(new rt_binary_expr<>(other),
00303 new op_unary<op_tan<default_numeric_type> >());
00304 }
00305
00307 template <typename LHS, typename OP>
00308 rt_unary_expr<> tan(ct_unary_expr<LHS, OP> const & other)
00309 {
00310 return rt_unary_expr<>(new rt_unary_expr<>(other),
00311 new op_unary<op_tan<default_numeric_type> >());
00312 }
00313
00315 template <typename InterfaceType>
00316 rt_unary_expr<InterfaceType> tan(rt_unary_expr<InterfaceType> const & other)
00317 {
00318 return rt_unary_expr<InterfaceType>(other.clone(), new op_unary<op_tan<typename InterfaceType::numeric_type>, InterfaceType>());
00319 }
00320
00322 template <typename InterfaceType>
00323 rt_unary_expr<InterfaceType> tan(rt_binary_expr<InterfaceType> const & other)
00324 {
00325 return rt_unary_expr<InterfaceType>(other.clone(), new op_unary<op_tan<typename InterfaceType::numeric_type>, InterfaceType>());
00326 }
00327
00329 template <typename InterfaceType>
00330 rt_unary_expr<InterfaceType> tan(rt_expr<InterfaceType> const & other)
00331 {
00332 return rt_unary_expr<InterfaceType>(other.get()->clone(), new op_unary<op_tan<typename InterfaceType::numeric_type>, InterfaceType>());
00333 }
00334
00335
00336
00337
00338
00340 template <typename InterfaceType, typename NumericT>
00341 InterfaceType * diff_impl(const InterfaceType * e, op_fabs<NumericT>, const InterfaceType * diff_var)
00342 {
00343 throw expression_not_differentiable_exception("modulus operation not differentiable!");
00344 return NULL;
00345 }
00346
00348 template <typename NumericT, typename InterfaceType>
00349 rt_unary_expr<InterfaceType> fabs(rt_constant<NumericT, InterfaceType> const & other)
00350 {
00351 return rt_unary_expr<InterfaceType>(other.clone(), new op_unary<op_fabs<typename InterfaceType::numeric_type>, InterfaceType>());
00352 }
00353
00355 template <typename InterfaceType>
00356 rt_unary_expr<InterfaceType> fabs(rt_variable<InterfaceType> const & other)
00357 {
00358 return rt_unary_expr<InterfaceType>(other.clone(), new op_unary<op_fabs<typename InterfaceType::numeric_type>, InterfaceType>());
00359 }
00360
00362 template <id_type id>
00363 rt_unary_expr<> fabs(ct_variable<id> const & other)
00364 {
00365 return rt_unary_expr<>(new rt_variable<>(id), new op_unary<op_fabs<default_numeric_type> >());
00366 }
00367
00369 template <typename LHS, typename OP, typename RHS>
00370 rt_unary_expr<> fabs(ct_binary_expr<LHS, OP, RHS> const & other)
00371 {
00372 return rt_unary_expr<>(new rt_binary_expr<>(other),
00373 new op_unary<op_fabs<default_numeric_type> >());
00374 }
00375
00377 template <typename LHS, typename OP>
00378 rt_unary_expr<> fabs(ct_unary_expr<LHS, OP> const & other)
00379 {
00380 return rt_unary_expr<>(new rt_unary_expr<>(other),
00381 new op_unary<op_fabs<default_numeric_type> >());
00382 }
00383
00384
00386 template <typename InterfaceType>
00387 rt_unary_expr<InterfaceType> fabs(rt_unary_expr<InterfaceType> const & other)
00388 {
00389 return rt_unary_expr<InterfaceType>(other.clone(), new op_unary<op_fabs<typename InterfaceType::numeric_type>, InterfaceType>());
00390 }
00391
00393 template <typename InterfaceType>
00394 rt_unary_expr<InterfaceType> fabs(rt_binary_expr<InterfaceType> const & other)
00395 {
00396 return rt_unary_expr<InterfaceType>(other.clone(), new op_unary<op_fabs<typename InterfaceType::numeric_type>, InterfaceType>());
00397 }
00398
00400 template <typename InterfaceType>
00401 rt_unary_expr<InterfaceType> fabs(rt_expr<InterfaceType> const & other)
00402 {
00403 return rt_unary_expr<InterfaceType>(other.get()->clone(), new op_unary<op_fabs<typename InterfaceType::numeric_type>, InterfaceType>());
00404 }
00405
00406
00407
00408
00409
00411 template <typename InterfaceType, typename NumericT>
00412 InterfaceType * diff_impl(const InterfaceType * e, op_sqrt<NumericT>, const InterfaceType * diff_var)
00413 {
00414 return new rt_binary_expr<InterfaceType>( e->diff(diff_var),
00415 new op_binary<op_div<typename InterfaceType::numeric_type>, InterfaceType>(),
00416 new rt_binary_expr<InterfaceType>( new rt_constant<NumericT>(2),
00417 new op_binary<op_mult<typename InterfaceType::numeric_type>, InterfaceType>(),
00418 new rt_unary_expr<InterfaceType>(e->clone(),
00419 new op_unary<op_sqrt<NumericT>, InterfaceType>())
00420 )
00421 );
00422 }
00423
00425 template <typename NumericT, typename InterfaceType>
00426 rt_unary_expr<InterfaceType> sqrt(rt_constant<NumericT, InterfaceType> const & other)
00427 {
00428 return rt_unary_expr<InterfaceType>(other.clone(), new op_unary<op_sqrt<typename InterfaceType::numeric_type>, InterfaceType>());
00429 }
00430
00432 template <typename InterfaceType>
00433 rt_unary_expr<InterfaceType> sqrt(rt_variable<InterfaceType> const & other)
00434 {
00435 return rt_unary_expr<InterfaceType>(other.clone(), new op_unary<op_sqrt<typename InterfaceType::numeric_type>, InterfaceType>());
00436 }
00437
00439 template <id_type id>
00440 rt_unary_expr<> sqrt(ct_variable<id> const & other)
00441 {
00442 return rt_unary_expr<>(new rt_variable<>(id), new op_unary<op_sqrt<default_numeric_type> >());
00443 }
00444
00446 template <typename LHS, typename OP, typename RHS>
00447 rt_unary_expr<> sqrt(ct_binary_expr<LHS, OP, RHS> const & other)
00448 {
00449 return rt_unary_expr<>(new rt_binary_expr<>(other),
00450 new op_unary<op_sqrt<default_numeric_type> >());
00451 }
00452
00454 template <typename LHS, typename OP>
00455 rt_unary_expr<> sqrt(ct_unary_expr<LHS, OP> const & other)
00456 {
00457 return rt_unary_expr<>(new rt_unary_expr<>(other),
00458 new op_unary<op_sqrt<default_numeric_type> >());
00459 }
00460
00461
00463 template <typename InterfaceType>
00464 rt_unary_expr<InterfaceType> sqrt(rt_unary_expr<InterfaceType> const & other)
00465 {
00466 return rt_unary_expr<InterfaceType>(other.clone(), new op_unary<op_sqrt<typename InterfaceType::numeric_type>, InterfaceType>());
00467 }
00468
00470 template <typename InterfaceType>
00471 rt_unary_expr<InterfaceType> sqrt(rt_binary_expr<InterfaceType> const & other)
00472 {
00473 return rt_unary_expr<InterfaceType>(other.clone(), new op_unary<op_sqrt<typename InterfaceType::numeric_type>, InterfaceType>());
00474 }
00475
00477 template <typename InterfaceType>
00478 rt_unary_expr<InterfaceType> sqrt(rt_expr<InterfaceType> const & other)
00479 {
00480 return rt_unary_expr<InterfaceType>(other.get()->clone(), new op_unary<op_sqrt<typename InterfaceType::numeric_type>, InterfaceType>());
00481 }
00482
00483
00484
00485
00487 template <typename InterfaceType, typename NumericT>
00488 InterfaceType * diff_impl(const InterfaceType * e, op_log<NumericT>, const InterfaceType * diff_var)
00489 {
00490 return new rt_binary_expr<InterfaceType>( e->diff(diff_var),
00491 new op_binary<op_div<typename InterfaceType::numeric_type>, InterfaceType>(),
00492 new rt_unary_expr<InterfaceType>(e->clone())
00493 );
00494 }
00495
00497 template <typename NumericT, typename InterfaceType>
00498 rt_unary_expr<InterfaceType> log(rt_constant<NumericT, InterfaceType> const & other)
00499 {
00500 return rt_unary_expr<InterfaceType>(other.clone(), new op_unary<op_log<typename InterfaceType::numeric_type>, InterfaceType>());
00501 }
00502
00504 template <typename InterfaceType>
00505 rt_unary_expr<InterfaceType> log(rt_variable<InterfaceType> const & other)
00506 {
00507 return rt_unary_expr<InterfaceType>(other.clone(), new op_unary<op_log<typename InterfaceType::numeric_type>, InterfaceType>());
00508 }
00509
00511 template <id_type id>
00512 rt_unary_expr<> log(ct_variable<id> const & other)
00513 {
00514 return rt_unary_expr<>(new rt_variable<>(id), new op_unary<op_log<default_numeric_type> >());
00515 }
00516
00518 template <typename LHS, typename OP, typename RHS>
00519 rt_unary_expr<> log(ct_binary_expr<LHS, OP, RHS> const & other)
00520 {
00521 return rt_unary_expr<>(new rt_binary_expr<>(other),
00522 new op_unary<op_log<default_numeric_type> >());
00523 }
00524
00526 template <typename LHS, typename OP>
00527 rt_unary_expr<> log(ct_unary_expr<LHS, OP> const & other)
00528 {
00529 return rt_unary_expr<>(new rt_unary_expr<>(other),
00530 new op_unary<op_log<default_numeric_type> >());
00531 }
00532
00534 template <typename InterfaceType>
00535 rt_unary_expr<InterfaceType> log(rt_unary_expr<InterfaceType> const & other)
00536 {
00537 return rt_unary_expr<InterfaceType>(other.clone(), new op_unary<op_log<typename InterfaceType::numeric_type>, InterfaceType>());
00538 }
00539
00541 template <typename InterfaceType>
00542 rt_unary_expr<InterfaceType> log(rt_binary_expr<InterfaceType> const & other)
00543 {
00544 return rt_unary_expr<InterfaceType>(other.clone(), new op_unary<op_log<typename InterfaceType::numeric_type>, InterfaceType>());
00545 }
00546
00548 template <typename InterfaceType>
00549 rt_unary_expr<InterfaceType> log(rt_expr<InterfaceType> const & other)
00550 {
00551 return rt_unary_expr<InterfaceType>(other.get()->clone(), new op_unary<op_log<typename InterfaceType::numeric_type>, InterfaceType>());
00552 }
00553
00554
00555
00556
00557
00558
00559
00564 template <typename InterfaceType, typename NumericT>
00565 InterfaceType * diff_impl(const InterfaceType * e, op_log10<NumericT>, const InterfaceType * diff_var)
00566 {
00567 return new rt_binary_expr<InterfaceType>( e->diff(diff_var),
00568 new op_binary<op_div<typename InterfaceType::numeric_type>, InterfaceType>(),
00569 new rt_binary_expr<InterfaceType>( new rt_constant<NumericT, InterfaceType>( ::log(10.0) ),
00570 new op_binary<op_mult<typename InterfaceType::numeric_type>, InterfaceType>(),
00571 new rt_unary_expr<InterfaceType>(e->clone())
00572 )
00573 );
00574 }
00575
00577 template <typename NumericT, typename InterfaceType>
00578 rt_unary_expr<InterfaceType> log10(rt_constant<NumericT, InterfaceType> const & other)
00579 {
00580 return rt_unary_expr<InterfaceType>(other.clone(), new op_unary<op_log10<typename InterfaceType::numeric_type>, InterfaceType>());
00581 }
00582
00584 template <typename InterfaceType>
00585 rt_unary_expr<InterfaceType> log10(rt_variable<InterfaceType> const & other)
00586 {
00587 return rt_unary_expr<InterfaceType>(other.clone(), new op_unary<op_log10<typename InterfaceType::numeric_type>, InterfaceType>());
00588 }
00589
00591 template <id_type id>
00592 rt_unary_expr<> log10(ct_variable<id> const & other)
00593 {
00594 return rt_unary_expr<>(new rt_variable<>(id), new op_unary<op_log10<default_numeric_type> >());
00595 }
00596
00598 template <typename LHS, typename OP, typename RHS>
00599 rt_unary_expr<> log10(ct_binary_expr<LHS, OP, RHS> const & other)
00600 {
00601 return rt_unary_expr<>(new rt_binary_expr<>(other),
00602 new op_unary<op_log10<default_numeric_type> >());
00603 }
00604
00606 template <typename LHS, typename OP>
00607 rt_unary_expr<> log10(ct_unary_expr<LHS, OP> const & other)
00608 {
00609 return rt_unary_expr<>(new rt_unary_expr<>(other),
00610 new op_unary<op_log10<default_numeric_type> >());
00611 }
00612
00614 template <typename InterfaceType>
00615 rt_unary_expr<InterfaceType> log10(rt_unary_expr<InterfaceType> const & other)
00616 {
00617 return rt_unary_expr<InterfaceType>(other.clone(), new op_unary<op_log10<typename InterfaceType::numeric_type>, InterfaceType>());
00618 }
00619
00621 template <typename InterfaceType>
00622 rt_unary_expr<InterfaceType> log10(rt_binary_expr<InterfaceType> const & other)
00623 {
00624 return rt_unary_expr<InterfaceType>(other.clone(), new op_unary<op_log10<typename InterfaceType::numeric_type>, InterfaceType>());
00625 }
00626
00628 template <typename InterfaceType>
00629 rt_unary_expr<InterfaceType> log10(rt_expr<InterfaceType> const & other)
00630 {
00631 return rt_unary_expr<InterfaceType>(other.get()->clone(), new op_unary<op_log10<typename InterfaceType::numeric_type>, InterfaceType>());
00632 }
00633
00634
00636
00637
00638
00639
00641 template <typename InterfaceType, typename NumericT>
00642 InterfaceType * diff_impl(const InterfaceType * e, op_gradient<NumericT>, const InterfaceType * diff_var)
00643 {
00644 throw expression_not_differentiable_exception("Cannot differentiate gradient operator!");
00645 return NULL;
00646 }
00647
00649 template <typename InterfaceType>
00650 rt_unary_expr<InterfaceType> grad(rt_function_symbol<InterfaceType> const & other)
00651 {
00652 return rt_unary_expr<InterfaceType>(other.clone(), new op_unary<op_gradient<typename InterfaceType::numeric_type>, InterfaceType>());
00653 }
00654
00656 template <typename InterfaceType>
00657 rt_unary_expr<InterfaceType> grad(rt_unary_expr<InterfaceType> const & other)
00658 {
00659 return rt_unary_expr<InterfaceType>(other.clone(), new op_unary<op_gradient<typename InterfaceType::numeric_type>, InterfaceType>());
00660 }
00661
00662
00663
00664
00665
00667 template <typename InterfaceType, typename NumericT>
00668 InterfaceType * diff_impl(const InterfaceType * e, op_divergence<NumericT>, const InterfaceType * diff_var)
00669 {
00670 throw expression_not_differentiable_exception("Cannot differentiate divergence operator!");
00671 return NULL;
00672 }
00673
00675 template <typename InterfaceType>
00676 rt_unary_expr<InterfaceType> div(rt_expr<InterfaceType> const & other)
00677 {
00678 return rt_unary_expr<InterfaceType>(other.get()->clone(), new op_unary<op_divergence<typename InterfaceType::numeric_type>, InterfaceType>());
00679 }
00680
00682 template <typename InterfaceType>
00683 rt_unary_expr<InterfaceType> div(rt_unary_expr<InterfaceType> const & other)
00684 {
00685 return rt_unary_expr<InterfaceType>(other.clone(), new op_unary<op_divergence<typename InterfaceType::numeric_type>, InterfaceType>());
00686 }
00687
00689 template <typename InterfaceType>
00690 rt_unary_expr<InterfaceType> div(rt_binary_expr<InterfaceType> const & other)
00691 {
00692 return rt_unary_expr<InterfaceType>(other.clone(), new op_unary<op_divergence<typename InterfaceType::numeric_type>, InterfaceType>());
00693 }
00694
00696 template <typename InterfaceType>
00697 rt_unary_expr<InterfaceType> div(rt_function_symbol<InterfaceType> const & other)
00698 {
00699 return rt_unary_expr<InterfaceType>(other.clone(), new op_unary<op_divergence<typename InterfaceType::numeric_type>, InterfaceType>());
00700 }
00701
00702
00703
00704
00705
00706
00708 template <typename InterfaceType>
00709 rt_unary_expr<InterfaceType> laplace(rt_expr<InterfaceType> const & other)
00710 {
00711 return div(grad(other));
00712 }
00713
00715 template <typename InterfaceType>
00716 rt_unary_expr<InterfaceType> laplace(rt_function_symbol<InterfaceType> const & other)
00717 {
00718 return div(grad(other));
00719 }
00720
00721
00722
00723
00724
00726 template <typename InterfaceType, typename NumericT>
00727 InterfaceType * diff_impl(const InterfaceType * e, op_partial_deriv<NumericT>, const InterfaceType * diff_var)
00728 {
00729 throw expression_not_differentiable_exception("Cannot evaluate formal partial derivative. Use transformations first.");
00730 return NULL;
00731 }
00732
00733
00734
00735
00737 template <typename InterfaceType>
00738 InterfaceType * diff_impl(const InterfaceType * e, op_rt_integral<InterfaceType>, const InterfaceType * diff_var)
00739 {
00740 throw expression_not_differentiable_exception("Cannot differentiate runtime integration (yet)!");
00741 return NULL;
00742 }
00743
00745 template <typename InterfaceType>
00746 InterfaceType * diff_impl(const InterfaceType * e, op_rt_symbolic_integral<InterfaceType>, const InterfaceType * diff_var)
00747 {
00748 throw expression_not_differentiable_exception("Cannot differentiate runtime integration (yet)!");
00749 return NULL;
00750 }
00751
00752 }
00753
00754 #endif