• Main Page
  • Namespaces
  • Data Structures
  • Files
  • File List

/export/development/ViennaMath/viennamath/manipulation/detail/unary_operations.hpp

Go to the documentation of this file.
00001 #ifndef VIENNAMATH_UNARY_OPERATORS_MANIPULATION_HPP
00002 #define VIENNAMATH_UNARY_OPERATORS_MANIPULATION_HPP
00003 
00004 /* =======================================================================
00005    Copyright (c) 2012, Institute for Microelectronics,
00006                        Institute for Analysis and Scientific Computing,
00007                        TU Wien.
00008                              -----------------
00009                ViennaMath - Symbolic and Numerical Math in C++
00010                              -----------------
00011 
00012    Author:     Karl Rupp                          rupp@iue.tuwien.ac.at
00013 
00014    License:    MIT (X11), see file LICENSE in the ViennaMath base directory
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   // identity
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   // exponential
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   // sinus
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   // cosinus
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   // tangens
00261   //
00263   template <typename InterfaceType, typename NumericT>
00264   InterfaceType * diff_impl(const InterfaceType * e, op_tan<NumericT>, const InterfaceType * diff_var)
00265   {
00266     // 1/cos^2(e):
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   // absolute value
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;  //TODO: Think about returning a piecewise function here?
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   // square root
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   // natural logarithm (aka ln())
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   // logarithm, base 10
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   // gradient
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   // divergence 
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   // Convenience Function: Laplace operator
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   // partial derivative with respect to variable<id>:
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   // integral:
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

Generated on Wed Feb 29 2012 21:50:43 for ViennaMath by  doxygen 1.7.1