Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
iwr
amdis
Commits
27c3af63
Commit
27c3af63
authored
Oct 08, 2015
by
Praetorius, Simon
Browse files
make functions for expressions to generate operatorTerms and expression simplification updated
parent
4c469863
Changes
2
Hide whitespace changes
Inline
Side-by-side
AMDiS/src/Expressions.h
View file @
27c3af63
...
...
@@ -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.
...
...
AMDiS/src/expressions/simplify_expr.hpp
View file @
27c3af63
...
...
@@ -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,49 +160,139 @@ 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
;
static
type
eval
(
Subtract
<
CValue
<
0
>
,
Term
>
const
&
t
)
{
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
;
static
type
eval
(
Mult
<
CValue
<
0
>
,
Term
>
const
&
t
)
{
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
;
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
>
,
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,8 +300,91 @@ 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
{
...
...
@@ -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
;
...
...
@@ -325,10 +519,44 @@ namespace AMDiS
static
type
eval
(
Mult
<
CValue
<
N
>
,
Mult
<
CValue
<
M
>
,
X
>
>
const
&
t
)
{
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
;
...
...
@@ -336,29 +564,153 @@ namespace AMDiS
static
type
eval
(
Mult
<
CValue
<
N
>
,
Mult
<
X
,
CValue
<
M
>
>
>
const
&
t
)
{
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
;
// X = t.term1.term2
static
type
eval
(
Mult
<
Mult
<
CValue
<
M
>
,
X
>
,
CValue
<
N
>
>
const
&
t
)
{
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
;
// X = t.term1.term1
static
type
eval
(
Mult
<
Mult
<
X
,
CValue
<
M
>
>
,
CValue
<
N
>
>
const
&
t
)
{
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
;