Commit 27c3af63 authored by Praetorius, Simon's avatar Praetorius, Simon
Browse files

make functions for expressions to generate operatorTerms and expression simplification updated

parent 4c469863
...@@ -686,6 +686,80 @@ inline void addSOT(Operator& op, double term, int I, int J) ...@@ -686,6 +686,80 @@ inline void addSOT(Operator& op, double term, int I, int J)
} }
#if HAS_CXX11
template <class Term, class Result = void>
using ScalarTerm = typename boost::enable_if< boost::is_same<double, typename Term::value_type>, Result >::type;
template <class Term, class Result = void>
using VectorTerm = typename boost::enable_if< boost::is_same<WorldVector<double>, typename Term::value_type>, Result >::type;
template <class Term, class Result = void>
using MatrixTerm = typename boost::enable_if< boost::is_same<WorldMatrix<double>, typename Term::value_type>, Result >::type;
// === ZOT ===
template <class Term, class Result = GenericZeroOrderTerm<typename std::decay<Term>::type> >
ScalarTerm<typename std::decay<Term>::type, Result*>
make_zot(Term&& term)
{
return new Result(std::forward<Term>(term));
}
// === FOT ===
template <class Term, class Result = GenericFirstOrderTerm_1<typename std::decay<Term>::type> >
ScalarTerm<typename std::decay<Term>::type, Result*>
make_fot(Term&& term)
{
return new Result(std::forward<Term>(term));
}
template <class Term, class Result = GenericFirstOrderTerm_i<-1,typename std::decay<Term>::type> >
ScalarTerm<typename std::decay<Term>::type, Result*>
make_fot(Term&& term, int i)
{
return new Result(std::forward<Term>(term), i);
}
template <class Term, class Result = GenericFirstOrderTerm_b<typename std::decay<Term>::type> >
VectorTerm<typename std::decay<Term>::type, Result*>
make_fot(Term&& term)
{
return new Result(std::forward<Term>(term));
}
// === SOT ===
template <class Term, class Result = GenericSecondOrderTerm_1<typename std::decay<Term>::type> >
ScalarTerm<typename std::decay<Term>::type, Result*>
make_sot(Term&& term)
{
return new Result(std::forward<Term>(term));
}
template <class Term, class Result = GenericSecondOrderTerm_ij<-1,-1,typename std::decay<Term>::type> >
ScalarTerm<typename std::decay<Term>::type, Result*>
make_sot(Term&& term, int i, int j)
{
return new Result(std::forward<Term>(term), i, j);
}
template <class Term, class Result = GenericSecondOrderTerm_A<typename std::decay<Term>::type> >
MatrixTerm<typename std::decay<Term>::type, Result*>
make_sot(Term&& term)
{
return new Result(std::forward<Term>(term));
}
#endif
// ============================================================================= // =============================================================================
/// Create an expression functor by wrapping an AbstractFunction and evaluate it a coordinates. /// Create an expression functor by wrapping an AbstractFunction and evaluate it a coordinates.
......
...@@ -46,7 +46,7 @@ namespace AMDiS ...@@ -46,7 +46,7 @@ namespace AMDiS
namespace expressions namespace expressions
{ {
template<typename Term, typename Enabled = void> template<typename Term>
struct Simplify struct Simplify
{ {
typedef Term type; typedef Term type;
...@@ -96,6 +96,16 @@ namespace AMDiS ...@@ -96,6 +96,16 @@ namespace AMDiS
{ return CValue<N+M>(); } { return CValue<N+M>(); }
}; };
/// (N) - (M) -> (N-M)
template<int N, int M>
struct Simplify< Subtract<CValue<N>, CValue<M> > >
{
typedef CValue<N-M> type;
static type eval(Subtract<CValue<N>, CValue<M> > const& t)
{ return CValue<N-M>(); }
};
/// (N) * (M) -> (N*M) /// (N) * (M) -> (N*M)
template<int N, int M > template<int N, int M >
struct Simplify< Mult<CValue<N>, CValue<M> > > struct Simplify< Mult<CValue<N>, CValue<M> > >
...@@ -122,7 +132,7 @@ namespace AMDiS ...@@ -122,7 +132,7 @@ namespace AMDiS
{ {
/// X + 0 -> X /// X + 0 -> X
template<typename Term> template<typename Term>
struct Simplify< Add<Term, CValue<0> >, typename boost::enable_if_c<!traits::is_ct_value<Term>::value>::type > struct Simplify< Add<Term, CValue<0> > >
{ {
typedef typename Simplify<Term>::type type; typedef typename Simplify<Term>::type type;
...@@ -130,18 +140,19 @@ namespace AMDiS ...@@ -130,18 +140,19 @@ namespace AMDiS
{ return simplify(t.term1); } { return simplify(t.term1); }
}; };
/// 0 + X -> X /// (N) + 0 -> X
template<typename Term> template<int N>
struct Simplify< Add<CValue<0>, Term>, typename boost::enable_if_c<!traits::is_ct_value<Term>::value>::type > struct Simplify< Add<CValue<N>, CValue<0> > >
{ {
typedef typename Simplify<Term>::type type; typedef CValue<N> type;
static type eval(Add<CValue<0>, Term> const& t) static type eval(Add<CValue<N>, CValue<0> > const&)
{ return simplify(t.term2); } { return CValue<N>(); }
}; };
/// X - 0 -> X /// X - 0 -> X
template<typename Term> template<typename Term>
struct Simplify< Subtract<Term, CValue<0> >, typename boost::enable_if_c<!traits::is_ct_value<Term>::value>::type > struct Simplify< Subtract<Term, CValue<0> > >
{ {
typedef typename Simplify<Term>::type type; typedef typename Simplify<Term>::type type;
...@@ -149,49 +160,139 @@ namespace AMDiS ...@@ -149,49 +160,139 @@ namespace AMDiS
{ return simplify(t.term1); } { return simplify(t.term1); }
}; };
/// (N) - 0 -> (N)
template<int N>
struct Simplify< Subtract<CValue<N>, CValue<0> > >
{
typedef CValue<N> type;
static type eval(Subtract<CValue<N>, CValue<0> > const&)
{ return CValue<N>(); }
};
/// 0 + X -> X
template<typename Term>
struct Simplify< Add<CValue<0>, Term> >
{
typedef typename Simplify<Term>::type type;
static type eval(Add<CValue<0>, Term> const& t)
{ return simplify(t.term2); }
};
/// 0 + (N) -> (N)
template<int N>
struct Simplify< Add<CValue<0>, CValue<N> > >
{
typedef CValue<N> type;
static type eval(Add<CValue<0>, CValue<N> > const&)
{ return CValue<N>(); }
};
/// 0 - X -> -X /// 0 - X -> -X
template<typename Term> template<typename Term>
struct Simplify< Subtract<CValue<0>, Term>, typename boost::enable_if_c<!traits::is_ct_value<Term>::value>::type > struct Simplify< Subtract<CValue<0>, Term> >
{ {
typedef Negative<typename Simplify<Term>::type> type; typedef Negative<typename Simplify<Term>::type> type;
static type eval(Subtract<CValue<0>, Term> const& t) static type eval(Subtract<CValue<0>, Term> const& t)
{ return -simplify(t.term2); } { return -simplify(t.term2); }
}; };
/// 0 - (N) -> (-N)
template<int N>
struct Simplify< Subtract<CValue<0>, CValue<N> > >
{
typedef CValue<-N> type;
static type eval(Subtract<CValue<0>, CValue<N> > const&)
{ return CValue<-N>(); }
};
/// 0 - 0 -> 0
template<>
struct Simplify< Subtract<CValue<0>, CValue<0> > >
{
typedef CValue<0> type;
static type eval(Subtract<CValue<0>, CValue<0> > const&)
{ return type(); }
};
/// 0 + 0 -> 0
template<>
struct Simplify< Add<CValue<0>, CValue<0> > >
{
typedef CValue<0> type;
static type eval(Add<CValue<0>, CValue<0> > const&)
{ return type(); }
};
/// X * 0 -> 0 /// X * 0 -> 0
template<typename Term> template<typename Term>
struct Simplify< Mult<Term, CValue<0> >, typename boost::enable_if_c<!traits::is_ct_value<Term>::value>::type > struct Simplify< Mult<Term, CValue<0> > >
{ {
typedef CValue<0> type; typedef CValue<0> type;
static type eval(Mult<Term, CValue<0> > const& t) static type eval(Mult<Term, CValue<0> > const&)
{ return CValue<0>(); }
};
/// (N) * 0 -> 0
template<int N>
struct Simplify< Mult<CValue<N>, CValue<0> > >
{
typedef CValue<0> type;
static type eval(Mult<CValue<N>, CValue<0> > const&)
{ return CValue<0>(); } { return CValue<0>(); }
}; };
/// 0 * X -> 0 /// 0 * X -> 0
template<typename Term> template<typename Term>
struct Simplify< Mult<CValue<0>, Term>, typename boost::enable_if_c<!traits::is_ct_value<Term>::value>::type > struct Simplify< Mult<CValue<0>, Term> >
{ {
typedef CValue<0> type; typedef CValue<0> type;
static type eval(Mult<CValue<0>, Term> const& t) static type eval(Mult<CValue<0>, Term> const& t)
{ return CValue<0>(); } { return CValue<0>(); }
}; };
/// 0 * (N) -> 0
template<int N>
struct Simplify< Mult<CValue<0>, CValue<N> > >
{
typedef CValue<0> type;
static type eval(Mult<CValue<0>, CValue<N> > const&)
{ return CValue<0>(); }
};
/// X * 1 -> X /// X * 1 -> X
template<typename Term> template<typename Term>
struct Simplify< Mult<Term, CValue<1> >, typename boost::enable_if_c<!traits::is_ct_value<Term>::value>::type > struct Simplify< Mult<Term, CValue<1> > >
{ {
typedef typename Simplify<Term>::type type; typedef typename Simplify<Term>::type type;
static type eval(Mult<Term, CValue<1> > const& t) static type eval(Mult<Term, CValue<1> > const& t)
{ return simplify(t.term1); } { return simplify(t.term1); }
}; };
/// (N) * 1 -> (N)
template<int N>
struct Simplify< Mult<CValue<N>, CValue<1> > >
{
typedef CValue<N> type;
static type eval(Mult<CValue<N>, CValue<1> > const&)
{ return CValue<N>(); }
};
/// 1 * X -> X /// 1 * X -> X
template<typename Term> template<typename Term>
struct Simplify< Mult<CValue<1>, Term>, typename boost::enable_if_c<!traits::is_ct_value<Term>::value>::type > struct Simplify< Mult<CValue<1>, Term> >
{ {
typedef typename Simplify<Term>::type type; typedef typename Simplify<Term>::type type;
...@@ -199,8 +300,91 @@ namespace AMDiS ...@@ -199,8 +300,91 @@ namespace AMDiS
{ return simplify(t.term2); } { return simplify(t.term2); }
}; };
/// 1 * (N) -> (N)
template<int N>
struct Simplify< Mult<CValue<1>, CValue<N> > >
{
typedef CValue<N> type;
static type eval(Mult<CValue<1>, CValue<N> > const&)
{ return CValue<N>(); }
};
/// X * -1 -> -X
template<typename Term>
struct Simplify< Mult<Term, CValue<-1> > >
{
typedef Negative<typename Simplify<Term>::type> type;
static type eval(Mult<Term, CValue<-1> > const& t)
{ return -simplify(t.term1); }
};
/// (N) * -1 -> (-N)
template<int N>
struct Simplify< Mult<CValue<N>, CValue<-1> > >
{
typedef CValue<-N> type;
static type eval(Mult<CValue<N>, CValue<-1> > const&)
{ return CValue<-N>(); }
};
/// -1 * X -> -X
template<typename Term>
struct Simplify< Mult<CValue<-1>, Term> >
{
typedef Negative<typename Simplify<Term>::type> type;
static type eval(Mult<CValue<-1>, Term> const& t)
{ return -simplify(t.term2); }
};
/// -1 * (N) -> (-N)
template<int N>
struct Simplify< Mult<CValue<-1>, CValue<N> > >
{
typedef CValue<-N> type;
static type eval(Mult<CValue<-1>, CValue<N> > const&)
{ return type(); }
};
#define MULT_CVALUE_IMPL(_A_,_B_) \
template<> struct Simplify< Mult<CValue<_A_>, CValue<_B_> > > { \
typedef CValue<_A_ * _B_> type; \
static type eval(Mult<CValue<_A_>, CValue<_B_> > const&) { return type(); } \
};
// implement all specializations with special values
MULT_CVALUE_IMPL(0,0)
MULT_CVALUE_IMPL(0,1)
MULT_CVALUE_IMPL(1,0)
MULT_CVALUE_IMPL(1,1)
MULT_CVALUE_IMPL(0,-1)
MULT_CVALUE_IMPL(-1,0)
MULT_CVALUE_IMPL(-1,-1)
MULT_CVALUE_IMPL(1,-1)
MULT_CVALUE_IMPL(-1,1)
} // end namespace expressions } // end namespace expressions
namespace expressions
{
// move constants to the beginning of the expression
// /// X * N -> N * X
// template<int N, typename Term>
// struct Simplify< Mult<Term, CValue<N> > >
// {
// typedef Mult<CValue<N>, Term> type;
//
// static type eval(Mult<Term, CValue<N> > const& t)
// { return CValue<N>() * t.term1; }
// };
} // end namespace expressions
namespace expressions namespace expressions
{ {
...@@ -244,14 +428,24 @@ namespace AMDiS ...@@ -244,14 +428,24 @@ namespace AMDiS
{ return t.term.term; } { return t.term.term; }
}; };
/// -(X - Y) -> Y - X /// (X + (-Y)) -> X - Y
template<typename X, typename Y> template<typename X, typename Y>
struct Simplify< Negative<Add<X, Negative<Y> > > > struct Simplify< Negative<Add<X, Negative<Y> > > >
{ {
typedef Add<Y, Negative<X> > type; typedef Subtract<X, Y> type;
static type eval(Negative<Add<X, Negative<Y> > > const& t) static type eval(Negative<Add<X, Negative<Y> > > const& t)
{ return t.term.term2.term - t.term.term1; } { return t.term1 - t.term2.term; }
};
/// -(X - Y) -> Y - X
template<typename X, typename Y>
struct Simplify< Negative<Subtract<X, Y> > >
{
typedef Subtract<Y, X> type;
static type eval(Negative<Subtract<X, Y> > const& t)
{ return t.term.term2 - t.term.term1; }
}; };
} // end namespace expressions } // end namespace expressions
...@@ -261,7 +455,7 @@ namespace AMDiS ...@@ -261,7 +455,7 @@ namespace AMDiS
{ {
/// X^1 -> X /// X^1 -> X
template<typename Term> template<typename Term>
struct Simplify< Pow<1, Term>, typename boost::enable_if_c<!traits::is_ct_value<Term>::value>::type > struct Simplify< Pow<1, Term> >
{ {
typedef Term type; typedef Term type;
...@@ -270,7 +464,7 @@ namespace AMDiS ...@@ -270,7 +464,7 @@ namespace AMDiS
/// X^0 -> 1 /// X^0 -> 1
template<typename Term> template<typename Term>
struct Simplify< Pow<0, Term>, typename boost::enable_if_c<!traits::is_ct_value<Term>::value>::type > struct Simplify< Pow<0, Term> >
{ {
typedef CValue<1> type; typedef CValue<1> type;
...@@ -317,7 +511,7 @@ namespace AMDiS ...@@ -317,7 +511,7 @@ namespace AMDiS
/// N*(M*X) -> (N*M) * X /// N*(M*X) -> (N*M) * X
template<int N, int M, typename X> template<int N, int M, typename X>
struct Simplify< Mult<CValue<N>, Mult<CValue<M>, X> >, typename boost::enable_if_c< N!=0 && N!=1 && M!=0 && M!=1 >::type > struct Simplify< Mult<CValue<N>, Mult<CValue<M>, X> > >
{ {
typedef Mult<CValue<N*M>, X> type; typedef Mult<CValue<N*M>, X> type;
...@@ -325,10 +519,44 @@ namespace AMDiS ...@@ -325,10 +519,44 @@ namespace AMDiS
static type eval(Mult<CValue<N>, Mult<CValue<M>, X> > const& t) static type eval(Mult<CValue<N>, Mult<CValue<M>, X> > const& t)
{ return CValue<N*M>() * (t.term2.term2); } { return CValue<N*M>() * (t.term2.term2); }
}; };
/// 0*(M*X) -> 0
template<int M, typename X>
struct Simplify< Mult<CValue<0>, Mult<CValue<M>, X> > >
{
typedef CValue<0> type;
// X = t.term2.term2
static type eval(Mult<CValue<0>, Mult<CValue<M>, X> > const& t)
{ return type(); }
};
/// 1*(M*X) -> M * X
template<int M, typename X>
struct Simplify< Mult<CValue<1>, Mult<CValue<M>, X> > >
{
typedef Mult<CValue<M>, X> type;
// X = t.term2.term2
static type eval(Mult<CValue<1>, Mult<CValue<M>, X> > const& t)
{ return CValue<M>() * (t.term2.term2); }
};
/// -1*(M*X) -> (-M) * X
template<int M, typename X>
struct Simplify< Mult<CValue<-1>, Mult<CValue<M>, X> > >
{
typedef Mult<CValue<-M>, X> type;
// X = t.term2.term2
static type eval(Mult<CValue<-1>, Mult<CValue<M>, X> > const& t)
{ return CValue<-M>() * (t.term2.term2); }
};
/// N*(X*M) -> (N*M) * X /// N*(X*M) -> (N*M) * X
template<int N, int M, typename X> template<int N, int M, typename X>
struct Simplify< Mult<CValue<N>, Mult<X, CValue<M> > >, typename boost::enable_if_c< N!=0 && N!=1 && M!=0 && M!=1 >::type > struct Simplify< Mult<CValue<N>, Mult<X, CValue<M> > > >
{ {
typedef Mult<CValue<N*M>, X> type; typedef Mult<CValue<N*M>, X> type;
...@@ -336,29 +564,153 @@ namespace AMDiS ...@@ -336,29 +564,153 @@ namespace AMDiS
static type eval(Mult<CValue<N>, Mult<X, CValue<M> > > const& t) static type eval(Mult<CValue<N>, Mult<X, CValue<M> > > const& t)
{ return CValue<N*M>() * (t.term2.term1); } { return CValue<N*M>() * (t.term2.term1); }
}; };
/// 0*(X*M) -> 0
template<int M, typename X>
struct Simplify< Mult<CValue<0>, Mult<X, CValue<M> > > >
{
typedef CValue<0> type;
// X = t.term2.term1
static type eval(Mult<CValue<0>, Mult<X, CValue<M> > > const& t)