00001 #ifndef VIENNAMATH_RUNTIME_BINARY_OPERATORS_HPP
00002 #define VIENNAMATH_RUNTIME_BINARY_OPERATORS_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 <iostream>
00023 #include <math.h>
00024 #include "viennamath/forwards.h"
00025 #include "viennamath/runtime/op_interface.hpp"
00026 #include "viennamath/compiletime/binary_op_tags.hpp"
00027
00032 namespace viennamath
00033 {
00034
00035
00036 template <typename InterfaceType, typename NumericT>
00037 InterfaceType * diff_impl(const InterfaceType * lhs, op_plus<NumericT>, const InterfaceType * rhs, const InterfaceType * diff_var);
00038
00039 template <typename InterfaceType, typename NumericT>
00040 InterfaceType * diff_impl(const InterfaceType * lhs, op_minus<NumericT>, const InterfaceType * rhs, const InterfaceType * diff_var);
00041
00042 template <typename InterfaceType, typename NumericT>
00043 InterfaceType * diff_impl(const InterfaceType * lhs, op_mult<NumericT>, const InterfaceType * rhs, const InterfaceType * diff_var);
00044
00045 template <typename InterfaceType, typename NumericT>
00046 InterfaceType * diff_impl(const InterfaceType * lhs, op_div<NumericT>, const InterfaceType * rhs, const InterfaceType * diff_var);
00047
00048
00049
00050 template <typename InterfaceType, typename NumericT>
00051 InterfaceType * simplify_impl(const InterfaceType * lhs, op_plus<NumericT>, const InterfaceType * rhs);
00052
00053 template <typename InterfaceType, typename NumericT>
00054 InterfaceType * simplify_impl(const InterfaceType * lhs, op_minus<NumericT>, const InterfaceType * rhs);
00055
00056 template <typename InterfaceType, typename NumericT>
00057 InterfaceType * simplify_impl(const InterfaceType * lhs, op_mult<NumericT>, const InterfaceType * rhs);
00058
00059 template <typename InterfaceType, typename NumericT>
00060 InterfaceType * simplify_impl(const InterfaceType * lhs, op_div<NumericT>, const InterfaceType * rhs);
00061
00062
00063 template <typename InterfaceType, typename NumericT>
00064 bool can_simplify_impl(const InterfaceType * lhs, op_plus<NumericT>, const InterfaceType * rhs);
00065
00066 template <typename InterfaceType, typename NumericT>
00067 bool can_simplify_impl(const InterfaceType * lhs, op_minus<NumericT>, const InterfaceType * rhs);
00068
00069 template <typename InterfaceType, typename NumericT>
00070 bool can_simplify_impl(const InterfaceType * lhs, op_mult<NumericT>, const InterfaceType * rhs);
00071
00072 template <typename InterfaceType, typename NumericT>
00073 bool can_simplify_impl(const InterfaceType * lhs, op_div<NumericT>, const InterfaceType * rhs);
00074
00075
00077
00083 template <typename BinaryOperation, typename InterfaceType>
00084 class op_binary : public op_interface<InterfaceType>
00085 {
00086 public:
00087 typedef typename InterfaceType::numeric_type numeric_type;
00088
00089
00090
00092 std::string str() const { return BinaryOperation::str(); }
00093
00095 op_interface<InterfaceType> * clone() const { return new op_binary<BinaryOperation, InterfaceType>(); }
00096
00098 numeric_type apply(numeric_type lhs, numeric_type rhs) const { return BinaryOperation::apply(lhs, rhs); }
00099
00101 bool is_unary() const { return false; }
00102
00104 InterfaceType * diff(const InterfaceType * lhs,
00105 const InterfaceType * rhs,
00106 const InterfaceType * diff_var) const
00107 {
00108 return diff_impl(lhs, BinaryOperation(), rhs, diff_var);
00109 }
00110
00112 InterfaceType * simplify(const InterfaceType * lhs,
00113 const InterfaceType * rhs) const
00114 {
00115 return simplify_impl(lhs, BinaryOperation(), rhs);
00116 }
00117
00119 bool can_simplify() const { std::cerr << "Warning in op_binary::optimizable(): Call without action" << std::endl; return false; }
00120
00121 bool can_simplify(const InterfaceType * lhs,
00122 const InterfaceType * rhs) const
00123 {
00124 return can_simplify_impl(lhs, BinaryOperation(), rhs);
00125 }
00126
00128 bool equal(const op_interface<InterfaceType> * other) const
00129 {
00130 return (dynamic_cast<const op_binary<BinaryOperation, InterfaceType> *>(other) != NULL);
00131 }
00132
00133 };
00134
00135
00136
00137
00138 }
00139
00140 #endif