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)
}
#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.
......
......@@ -46,7 +46,7 @@ namespace AMDiS
namespace expressions
{
template<typename Term, typename Enabled = void>
template<typename Term>
struct Simplify
{
typedef Term type;
......@@ -96,6 +96,16 @@ namespace AMDiS
{ 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)
template<int N, int M >
struct Simplify< Mult<CValue<N>, CValue<M> > >
......@@ -122,7 +132,7 @@ namespace AMDiS
{
/// X + 0 -> X
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;
......@@ -130,18 +140,19 @@ namespace AMDiS
{ return simplify(t.term1); }
};
/// 0 + X -> X
template<typename Term>
struct Simplify< Add<CValue<0>, Term>, typename boost::enable_if_c<!traits::is_ct_value<Term>::value>::type >
/// (N) + 0 -> X
template<int N>
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)
{ return simplify(t.term2); }
static type eval(Add<CValue<N>, CValue<0> > const&)
{ return CValue<N>(); }
};
/// X - 0 -> X
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;
......@@ -149,9 +160,39 @@ namespace AMDiS
{ 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
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;
......@@ -159,19 +200,59 @@ namespace AMDiS
{ 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
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;
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>(); }
};
/// 0 * X -> 0
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;
......@@ -179,9 +260,19 @@ namespace AMDiS
{ 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
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;
......@@ -189,9 +280,19 @@ namespace AMDiS
{ 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>, typename boost::enable_if_c<!traits::is_ct_value<Term>::value>::type >
struct Simplify< Mult<CValue<1>, Term> >
{
typedef typename Simplify<Term>::type type;
......@@ -199,9 +300,92 @@ namespace AMDiS
{ 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
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
{
/// X / X -> 1
......@@ -244,14 +428,24 @@ namespace AMDiS
{ return t.term.term; }
};
/// -(X - Y) -> Y - X
/// (X + (-Y)) -> X - Y
template<typename X, typename 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)
{ 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
......@@ -261,7 +455,7 @@ namespace AMDiS
{
/// X^1 -> X
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;
......@@ -270,7 +464,7 @@ namespace AMDiS
/// X^0 -> 1
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;
......@@ -317,7 +511,7 @@ namespace AMDiS
/// N*(M*X) -> (N*M) * 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;
......@@ -326,9 +520,43 @@ namespace AMDiS
{ 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
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;
......@@ -337,10 +565,43 @@ namespace AMDiS
{ 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)
{ return type(); }
};
/// 1*(X*M) -> M * X
template<int M, typename X>
struct Simplify< Mult<CValue<1>, Mult<X, CValue<M> > > >
{
typedef Mult<CValue<M>, X> type;
// X = t.term2.term1
static type eval(Mult<CValue<1>, Mult<X, CValue<M> > > const& t)
{ return CValue<M>() * (t.term2.term1); }
};
/// -1*(X*M) -> (-M) * X
template<int M, typename X>
struct Simplify< Mult<CValue<-1>, Mult<X, CValue<M> > > >
{
typedef Mult<CValue<-M>, X> type;
// X = t.term2.term1
static type eval(Mult<CValue<-1>, Mult<X, CValue<M> > > const& t)
{ return CValue<-M>() * (t.term2.term1); }
};
/// (M*X)*N -> (N*M) * X
template<int N, int M, typename X>
struct Simplify< Mult<Mult<CValue<M>, X>, CValue<N> >, typename boost::enable_if_c< N!=0 && N!=1 && M!=0 && M!=1 >::type >
struct Simplify< Mult<Mult<CValue<M>, X>, CValue<N> > >
{
typedef Mult<CValue<N*M>, X> type;
......@@ -349,10 +610,43 @@ namespace AMDiS
{ return CValue<N*M>() * (t.term1.term2); }
};
/// (M*X)*0 -> 0
template<int M, typename X>
struct Simplify< Mult<Mult<CValue<M>, X>, CValue<0> > >
{
typedef CValue<0> type;
// X = t.term1.term2
static type eval(Mult<Mult<CValue<M>, X>, CValue<0> > const& t)
{ return type(); }
};
/// (M*X)*1 -> M * X
template<int M, typename X>
struct Simplify< Mult<Mult<CValue<M>, X>, CValue<1> > >
{
typedef Mult<CValue<M>, X> type;
// X = t.term1.term2
static type eval(Mult<Mult<CValue<M>, X>, CValue<1> > const& t)
{ return CValue<M>() * (t.term1.term2); }
};
/// (M*X)*-1 -> (-M) * X
template<int M, typename X>
struct Simplify< Mult<Mult<CValue<M>, X>, CValue<-1> > >
{
typedef Mult<CValue<-M>, X> type;
// X = t.term1.term2
static type eval(Mult<Mult<CValue<M>, X>, CValue<-1> > const& t)
{ return CValue<-M>() * (t.term1.term2); }
};
/// (X*M)*N -> (N*M) * X
template<int N, int M, typename X>
struct Simplify< Mult<Mult<X, CValue<M> >, CValue<N> >, typename boost::enable_if_c< N!=0 && N!=1 && M!=0 && M!=1 >::type >
struct Simplify< Mult<Mult<X, CValue<M> >, CValue<N> > >
{
typedef Mult<CValue<N*M>, X> type;
......@@ -361,6 +655,64 @@ namespace AMDiS
{ return CValue<N*M>() * (t.term1.term1); }
};
/// (X*M)*0 -> 0
template<int M, typename X>
struct Simplify< Mult<Mult<X, CValue<M> >, CValue<0> > >
{
typedef CValue<0> type;
// X = t.term1.term1
static type eval(Mult<Mult<X, CValue<M> >, CValue<0> > const& t)
{ return type(); }
};
/// (X*M)*1 -> M * X
template<int M, typename X>
struct Simplify< Mult<Mult<X, CValue<M> >, CValue<1> > >