00001
00002
00014
00015
00016 #ifndef polybori_groebner_LLReduction_h_
00017 #define polybori_groebner_LLReduction_h_
00018
00019
00020 #include "groebner_defs.h"
00021
00022 BEGIN_NAMESPACE_PBORIGB
00023
00028 template <bool have_redsb, bool single_call_for_noredsb,
00029 bool fast_multiplication>
00030 class LLReduction {
00031 public:
00032
00033 template<class RingType>
00034 LLReduction(const RingType& ring): cache_mgr(ring) {}
00035
00036 Polynomial multiply(const Polynomial &p, const Polynomial& q){
00037 typedef CommutativeCacheManager<CCacheTypes::multiply_recursive>
00038 cache_mgr_type;
00039
00040 return dd_multiply<fast_multiplication>(cache_mgr_type(p.ring()),
00041 p.navigation(), q.navigation(),
00042 BoolePolynomial(p.ring()));
00043 }
00044
00045 Polynomial operator()(const Polynomial& p, MonomialSet::navigator r_nav);
00046
00047 protected:
00048 typedef PBORI::CacheManager<CCacheTypes::ll_red_nf> cache_mgr_type;
00049 cache_mgr_type cache_mgr;
00050 };
00051
00052
00053 template <bool have_redsb, bool single_call_for_noredsb, bool fast_multiplication>
00054 Polynomial
00055 LLReduction<have_redsb, single_call_for_noredsb,
00056 fast_multiplication>::operator() (const Polynomial& p,
00057 MonomialSet::navigator r_nav) {
00058
00059 if PBORI_UNLIKELY(p.isConstant()) return p;
00060
00061 MonomialSet::navigator p_nav=p.navigation();
00062 idx_type p_index=*p_nav;
00063
00064 while((*r_nav)<p_index) {
00065 r_nav.incrementThen();
00066 }
00067
00068 if PBORI_UNLIKELY(r_nav.isConstant())
00069 return p;
00070
00071 MonomialSet::navigator cached = cache_mgr.find(p_nav, r_nav);
00072
00073 if PBORI_LIKELY(cached.isValid())
00074 return MonomialSet(cache_mgr.generate(cached));
00075
00076 Polynomial res(0, p.ring());
00077
00078 Polynomial p_nav_else(cache_mgr.generate(p_nav.elseBranch()));
00079 Polynomial p_nav_then(cache_mgr.generate(p_nav.thenBranch()));
00080
00081 if ((*r_nav) == p_index){
00082 Polynomial r_nav_else(cache_mgr.generate(r_nav.elseBranch()));
00083
00084 if ((!have_redsb) && single_call_for_noredsb) {
00085 res = operator()(p_nav_else + multiply(r_nav_else, p_nav_then),
00086 r_nav.thenBranch());
00087 }
00088 else {
00089 Polynomial tmp1 = operator()(p_nav_else, r_nav.thenBranch());
00090 Polynomial tmp2 = operator()(p_nav_then, r_nav.thenBranch());
00091
00092 Polynomial tmp( have_redsb? r_nav_else:
00093 operator()(r_nav_else, r_nav.thenBranch()) );
00094 res = tmp1 + multiply(tmp, tmp2);
00095 }
00096 }
00097 else{
00098 PBORI_ASSERT((*r_nav)>p_index);
00099 res = MonomialSet( p_index,
00100 operator()(p_nav_then, r_nav).diagram(),
00101 operator()(p_nav_else, r_nav).diagram());
00102
00103 }
00104
00105 cache_mgr.insert(p_nav, r_nav, res.navigation());
00106 return res;
00107 }
00108
00109 END_NAMESPACE_PBORIGB
00110
00111 #endif