// new_m is a monomial that we have just created. There are several // things that can happen: // (1) new_m is already in the hash table (as is). // i.e. we have already processed this monomial. // in this case new_m[-1] is the index of the divisor for this monomial // (possibly -1). // (2) new_m is a newly seen monomial in this degree. // insert it into the hash table as a seen monomial // we set the divisor for new_m: either -1 or some index // If there is no divisor, return -1. // If there is: create a row, and push onto the mReducers list. // (2A) ComponentIndex F4Res::processCurrentMonomial(res_packed_monomial thisMonom) { res_packed_monomial new_m; // a pointer to a monomial we are visiting if (mHashTable.find_or_insert(thisMonom, new_m)) { // we did not need the monomial. So pop it. mMonomSpace2.popLastAlloc(thisMonom-1); return static_cast<ComponentIndex>( new_m[-1]); // monom exists, don't save monomial space } // At this point thisMonom has been inserted. We keep it. thisMonom = mMonomSpace2.allocate(1 + monoid().max_monomial_size()); thisMonom++; // so thisMonom[-1] exists, but is not part of the monomial, as far as bool has_divisor = findDivisor(new_m, thisMonom); if (!has_divisor) { mMonomSpace2.popLastAlloc(thisMonom-1); new_m[-1] = -1; // no divisor exists return -1; } ComponentIndex thiscol = static_cast<ComponentIndex>(mColumns.size()); new_m[-1] = thiscol; // this is a HACK: where we keep the divisor mColumns.push_back(new_m); Row row; row.mLeadTerm = thisMonom; mReducers.push_back(row); return thiscol; }
// Reduce the leading term of f one step with the first polynomial g_i in the // intermediate basis that satisfies isLeadingReducibleBy(f,g_i) bool reduceLt(BRP &f, const IntermediateBasis &F, const IntermediateBasis::const_iterator itF) { bool ret = false; // true if anything was reduced IntermediateBasis::const_iterator it; IntermediateBasis::const_iterator end = F.end(); while( !f.isZero() && (it = findDivisor(f, F, itF)) != end ) { ret = true; cancelLeadTerm(f,it->second); } return ret; }
// new_m is a monomial that we have just created. There are several // things that can happen: // (1) new_m is already in the hash table (as is). // i.e. we have already processed this monomial. // in this case new_m[-1] is the index of the divisor for this monomial // (possibly -1). // (2) new_m is a newly seen monomial in this degree. // insert it into the hash table as a seen monomial // we set the divisor for new_m: either -1 or some index // If there is no divisor, return -1. // If there is: create a row, and push onto the mReducers list. // (2A) ComponentIndex F4Res::processCurrentMonomial() { res_packed_monomial new_m; // a pointer to a monomial we are visiting if (mHashTable.find_or_insert(mNextMonom, new_m)) return static_cast<ComponentIndex>( new_m[-1]); // monom exists, don't save monomial space // intern the monomial just inserted into the hash table mMonomSpace.intern(1 + monoid().monomial_size(mNextMonom)); // leave room for the next monomial. This might be set below. mNextMonom = mMonomSpace.reserve(1 + monoid().max_monomial_size()); mNextMonom++; bool has_divisor = findDivisor(new_m, mNextMonom); if (!has_divisor) { new_m[-1] = -1; // no divisor exists return -1; } mMonomSpace.intern(1 + monoid().monomial_size(mNextMonom)); ComponentIndex thiscol = static_cast<ComponentIndex>(mColumns.size()); new_m[-1] = thiscol; // this is a HACK: where we keep the divisor mColumns.push_back(new_m); Row row; row.mLeadTerm = mNextMonom; mReducers.push_back(row); // Now we increment mNextMonom, for the next time mNextMonom = mMonomSpace.reserve(1 + monoid().max_monomial_size()); mNextMonom++; return thiscol; }