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

/export/development/ViennaMath/viennamath/manipulation/eval.hpp

Go to the documentation of this file.
00001 #ifndef VIENNAMATH_MANIPULATION_EVAL_HPP
00002 #define VIENNAMATH_MANIPULATION_EVAL_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 "viennamath/forwards.h"
00021 #include "viennamath/compiletime/ct_variable.hpp"
00022 #include "viennamath/manipulation/simplify.hpp"
00023 
00028 namespace viennamath
00029 {
00031 
00032   namespace result_of
00033   {
00035     template <typename E>
00036     struct is_ct_evaluable
00037     {
00038       enum { value = 0 };
00039     };
00040     
00042     template <typename LHS, typename OP, typename RHS>
00043     struct is_ct_evaluable< ct_binary_expr<LHS, OP, RHS> >
00044     {
00045       enum { value = is_ct_evaluable<LHS>::value * is_ct_evaluable<RHS>::value };
00046     };
00047     
00049     template <long val>
00050     struct is_ct_evaluable< ct_constant<val> >
00051     {
00052       enum { value = 1 };
00053     };
00054     
00056     template <id_type id>
00057     struct is_ct_evaluable< ct_variable<id> >
00058     {
00059       enum { value = 1 };
00060     };
00061     
00063     template <typename VectorType>
00064     struct is_ct_vector
00065     {
00066       enum { value = 0 };
00067     };
00068 
00070     template <typename T0>
00071     struct is_ct_vector< ct_vector_1<T0> > 
00072     {
00073       enum { value = is_compiletime<T0>::value };
00074     };
00075 
00077     template <typename T0, typename T1>
00078     struct is_ct_vector< ct_vector_2<T0, T1> >
00079     {
00080       enum { value = is_compiletime<T0>::value && is_compiletime<T1>::value };
00081     };
00082 
00084     template <typename T0, typename T1, typename T2>
00085     struct is_ct_vector< ct_vector_3<T0, T1, T2> > 
00086     {
00087       enum { value = is_compiletime<T0>::value && is_compiletime<T1>::value && is_compiletime<T2>::value };
00088     };
00089     
00090     
00091     //
00092     // compile time evaluation metafunction
00093     
00100     template <typename ExpressionType,
00101               typename VectorType,
00102               bool ct_evaluable = (is_ct_evaluable<ExpressionType>::value != 0)>
00103     struct eval
00104     {
00105       typedef typename ExpressionType::ERROR_INVALID_EXPRESSION_TYPE_FOR_COMPILETIME_EVALUATION  error_type;
00106     };
00107     
00108     //valid arguments:
00110     template <typename LHS, typename OP, typename RHS, typename VectorType>
00111     struct eval< ct_binary_expr<LHS, OP, RHS>, VectorType, true>
00112     {
00113       typedef ct_binary_expr< typename eval<LHS, VectorType>::type,
00114                               OP,
00115                               typename eval<RHS, VectorType>::type >  intermediate_type;
00116       
00117       // run two rational evaluations in the following (the second ensures a resolution of a/1 and 0/b cases)
00118       typedef typename result_of::simplify<intermediate_type>::type   type;
00119     };
00120     
00122     template <long value, typename VectorType>
00123     struct eval< ct_constant<value>, VectorType, true>
00124     {
00125       typedef ct_constant<value>    type;
00126     };
00127     
00129     template <id_type id, typename VectorType>
00130     struct eval< ct_variable<id>, VectorType, true>
00131     {
00132       typedef typename type_by_index<VectorType, id>::type  type;
00133     };
00134     
00136     template <long value>
00137     struct eval< ct_variable<0>, ct_constant<value>, true>
00138     {
00139       typedef ct_constant<value>  type;
00140     };
00141     
00142   } //namespace result_of
00143   
00144   //the public interface function:
00150   template <typename ExpressionType, typename VectorType>
00151   typename enable_if<result_of::is_ct_evaluable<ExpressionType>::value && result_of::is_ct_vector<VectorType>::value,
00152                      default_numeric_type>::type 
00153   eval(ExpressionType const & e, VectorType const & v)
00154   {
00155     return typename result_of::eval<ExpressionType, VectorType>::type()();
00156   }
00157   
00158 
00159   
00161   
00162   /*template <typename ExpressionType, typename VectorType>
00163   typename ExpressionType::numeric_type eval(ExpressionType const & e, VectorType const & v)
00164   {
00165     //generic approach: use operator() and hope the best:
00166     return e(v);
00167   }*/
00168 
00170   template <typename VectorType>
00171   default_numeric_type eval(default_numeric_type value, VectorType const & v)
00172   {
00173     //generic approach: use operator() and hope the best:
00174     return value;
00175   }
00176 
00178   template <typename VectorType>
00179   long eval(long value, VectorType const & v)
00180   {
00181     //generic approach: use operator() and hope the best:
00182     return value;
00183   }
00184 
00186   template <typename T, typename InterfaceType, typename VectorType>
00187   typename InterfaceType::numeric_type
00188   eval(rt_constant<T, InterfaceType> c, VectorType const & v)
00189   {
00190     //generic approach: use operator() and hope the best:
00191     return c();
00192   }
00193 
00199   template <typename InterfaceType, typename VectorType>
00200   typename InterfaceType::numeric_type
00201   eval(rt_expr< InterfaceType> e, VectorType const & v)
00202   {
00203     return e(v);
00204   }
00205 
00211   template <typename InterfaceType, typename VectorType>
00212   typename InterfaceType::numeric_type
00213   eval(rt_binary_expr< InterfaceType> e, VectorType const & v)
00214   {
00215     return e(v);
00216   }
00217 
00223   template <typename InterfaceType, typename VectorType>
00224   typename InterfaceType::numeric_type
00225   eval(rt_unary_expr< InterfaceType> e, VectorType const & v)
00226   {
00227     return e(v);
00228   }
00229 
00235   template <typename InterfaceType, typename VectorType>
00236   typename InterfaceType::numeric_type
00237   eval(rt_variable< InterfaceType> e, VectorType const & v)
00238   {
00239     return e(v);
00240   }
00241 
00242 
00243 
00249   template <typename LHS, typename OP, typename RHS, typename VectorType>
00250   typename enable_if<!result_of::is_ct_evaluable< ct_binary_expr<LHS, OP, RHS> >::value || !result_of::is_ct_vector<VectorType>::value,
00251                      default_numeric_type>::type 
00252   eval(ct_binary_expr<LHS, OP, RHS> ex, VectorType const & v)
00253   {
00254     return ex(v);
00255   }
00256   
00262   template <typename LHS, typename OP, typename VectorType>
00263   typename enable_if<!result_of::is_ct_evaluable< ct_unary_expr<LHS, OP> >::value || !result_of::is_ct_vector<VectorType>::value,
00264                      default_numeric_type>::type 
00265   eval(ct_unary_expr<LHS, OP> ex, VectorType const & v)
00266   {
00267     return ex(v);
00268   }
00269 
00275   template <long value, typename VectorType>
00276   default_numeric_type eval(ct_constant<value> c, VectorType const & v)
00277   {
00278     return value;
00279   }
00280 
00286   template <id_type id, typename VectorType>
00287   default_numeric_type eval(ct_variable<id> c, VectorType const & v)
00288   {
00289     return v[id];
00290   }
00291 
00293   template <id_type id, typename T0>
00294   default_numeric_type eval(ct_variable<id> c, ct_vector_1<T0> const & v)
00295   {
00296     return v[ct_index<id>()];
00297   }
00298 
00300   template <id_type id, typename T0, typename T1>
00301   default_numeric_type eval(ct_variable<id> c, ct_vector_2<T0, T1> const & v)
00302   {
00303     return v[ct_index<id>()];
00304   }
00305 
00307   template <id_type id, typename T0, typename T1, typename T2>
00308   default_numeric_type eval(ct_variable<id> c, ct_vector_3<T0, T1, T2> const & v)
00309   {
00310     return v[ct_index<id>()];
00311   }
00312 
00313 }
00314 
00315 #endif

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