RCP<const UnivariateIntPolynomial> mul_poly(const UnivariateIntPolynomial &a, const UnivariateIntPolynomial &b) { RCP<const Symbol> var = symbol(""); if (a.get_var()->get_name() == "") { var = b.get_var(); } else if (b.get_var()->get_name() == "") { var = a.get_var(); } else if (!(a.get_var()->__eq__(*b.get_var()))) { throw std::runtime_error("Error: variables must agree."); } else { var = a.get_var(); } bool neg = false; if ((--(a.get_dict().end()))->second < 0) neg = not neg; if ((--(b.get_dict().end()))->second < 0) neg = not neg; unsigned int N = bit_length(std::min(a.get_degree() + 1, b.get_degree() + 1)) + bit_length(a.max_abs_coef()) + bit_length(b.max_abs_coef()); integer_class a1(1), b1; a1 <<= N; integer_class a2 = a1 / 2; integer_class mask = a1 - 1; integer_class a_val(a.eval_bit(N)), b_val(b.eval_bit(N)); integer_class s_val(a_val * b_val); integer_class r = mp_abs(s_val); std::vector<integer_class> v; integer_class carry(0); while (r != 0 or carry != 0) { mp_and(b1, r, mask); if (b1 < a2) { v.push_back(b1 + carry); carry = 0; } else { v.push_back(b1 - a1 + carry); carry = 1; } r >>= N; } if (neg) return neg_poly(*UnivariateIntPolynomial::from_vec(var, v)); else return UnivariateIntPolynomial::from_vec(var, v); }
char *test_new() { a = bit_new(256); mu_assert(a != NULL, "bit_new returns NULL.\n"); mu_assert(bit_length(a) == 256, "bit_new returns wrong length.\n"); mu_assert(bit_count(a) == 0, "bit_new returns wrong count.\n"); b = bit_new(256); mu_assert(b != NULL, "bit_new returns NULL.\n"); mu_assert(bit_length(b) == 256, "bit_new returns wrong length.\n"); mu_assert(bit_count(b) == 0, "bit_new returns wrong count.\n"); return NULL; }
RCP<const UnivariatePolynomial> mul_uni_poly(RCP<const UnivariatePolynomial> a, RCP<const UnivariatePolynomial> b) { //TODO: Use `const RCP<const UnivariatePolynomial> &a` for input arguments, // even better is use `const UnivariatePolynomial &a` unsigned int da = a->degree_; unsigned int db = b->degree_; int sign = 1; if ((--(a->dict_.end()))->second < 0) { a = neg_uni_poly(*a); sign = -1 * sign; } if ((--(b->dict_.end()))->second < 0) { b = neg_uni_poly(*b); sign = -1 * sign; } mpz_class p = std::max(a->max_coef(), b->max_coef()); unsigned int N = bit_length(std::min(da + 1, db + 1)) + bit_length(p) + 1; mpz_class a1 = 1 << N; mpz_class a2 = a1 / 2; mpz_class mask = a1 - 1; mpz_class sa = a->eval_bit(N); mpz_class sb = b->eval_bit(N); mpz_class r = sa*sb; std::vector<mpz_class> v; mpz_class carry = 0; while (r != 0 or carry != 0) { mpz_class b; mpz_and(b.get_mpz_t(), r.get_mpz_t(), mask.get_mpz_t()); if (b < a2) { v.push_back(b + carry); carry = 0; } else { v.push_back(b - a1 + carry); carry = 1; } r >>= N; } if (sign == -1) return neg_uni_poly(*make_rcp<const UnivariatePolynomial>(a->var_, v)); else return make_rcp<const UnivariatePolynomial>(a->var_, v); }
void DnaPacker::PackToBin(const DnaBin &dnaBin_, BitMemoryWriter& metaWriter_, BitMemoryWriter& dnaWriter_, BinaryBinDescriptor& binDesc_, bool cutMinimizer_) { const uint32 recordsCount = dnaBin_.Size(); const uint64 initialMetaPos = metaWriter_.Position(); const uint64 initialDnaPos = dnaWriter_.Position(); binDesc_.recordsCount = recordsCount; if (recordsCount == 0) return; ASSERT(recordsCount < (1 << 28)); ASSERT(dnaBin_.GetStats().maxLen > 0); ASSERT(dnaBin_.GetStats().maxLen >= dnaBin_.GetStats().minLen); BinPackSettings settings; settings.minLen = dnaBin_.GetStats().minLen; settings.maxLen = dnaBin_.GetStats().maxLen; settings.hasConstLen = (settings.minLen == settings.maxLen); if (!cutMinimizer_) settings.suffixLen = params.signatureSuffixLen; else settings.suffixLen = 0; metaWriter_.PutBits(dnaBin_.GetStats().minLen, LenBits); metaWriter_.PutBits(dnaBin_.GetStats().maxLen, LenBits); if (!settings.hasConstLen) settings.bitsPerLen = bit_length(dnaBin_.GetStats().maxLen - dnaBin_.GetStats().minLen); for (uint32 i = 0; i < recordsCount; ++i) { const DnaRecord& drec = dnaBin_[i]; StoreNextRecord(drec, metaWriter_, dnaWriter_, settings); binDesc_.rawDnaSize += drec.len; } metaWriter_.FlushPartialWordBuffer(); dnaWriter_.FlushPartialWordBuffer(); binDesc_.metaSize = metaWriter_.Position() - initialMetaPos; binDesc_.dnaSize = dnaWriter_.Position() - initialDnaPos; }
void DnaPacker::UnpackFromBin(const BinaryBinBlock& binBin_, DnaBin& dnaBin_, uint32 minimizerId_, DataChunk& dnaChunk_, bool append_) { // calculate global bin properties // uint64 recordsCount = 0; for (uint32 i = 0; i < binBin_.descriptors.size(); ++i) { const BinaryBinDescriptor& desc = binBin_.descriptors[i]; recordsCount += desc.recordsCount; } ASSERT(recordsCount < (1 << 28)); // initialize // uint64 recId = 0; if (append_) { recId = dnaBin_.Size(); recordsCount += recId; ASSERT(dnaChunk_.data.Size() >= dnaChunk_.size + binBin_.rawDnaSize); } else { dnaBin_.Clear(); dnaChunk_.size = 0; if (dnaChunk_.data.Size() < binBin_.rawDnaSize) dnaChunk_.data.Extend(binBin_.rawDnaSize); } dnaBin_.Resize(recordsCount); if (recordsCount == 0) return; // configure settings // BinPackSettings settings; char minString[64] = {0}; if (minimizerId_ != params.TotalMinimizersCount()) // N bin? { settings.suffixLen = params.signatureSuffixLen; params.GenerateMinimizer(minimizerId_, minString); } else { settings.suffixLen = 0; } BitMemoryReader metaReader(binBin_.metaData, binBin_.metaSize); BitMemoryReader dnaReader(binBin_.dnaData, binBin_.dnaSize); char* dnaBufferPtr = (char*)dnaChunk_.data.Pointer(); for (uint32 i = 0; i < binBin_.descriptors.size(); ++i) { const BinaryBinDescriptor& desc = binBin_.descriptors[i]; const uint64 initialMetaPos = metaReader.Position(); const uint64 initialDnaPos = dnaReader.Position(); // read bin header // settings.minLen = metaReader.GetBits(LenBits); settings.maxLen = metaReader.GetBits(LenBits); ASSERT(settings.minLen > 0); ASSERT(settings.maxLen >= settings.minLen); settings.hasConstLen = (settings.minLen == settings.maxLen); if (!settings.hasConstLen) { settings.bitsPerLen = bit_length(settings.maxLen - settings.minLen); ASSERT(settings.bitsPerLen > 0); } // read bin records // if (settings.suffixLen > 0) { for (uint32 j = 0; j < desc.recordsCount; ++j) { DnaRecord& rec = dnaBin_[recId++]; rec.dna = dnaBufferPtr + dnaChunk_.size; bool b = ReadNextRecord(metaReader, dnaReader, rec, settings); ASSERT(b); ASSERT(dnaChunk_.size + rec.len <= dnaChunk_.data.Size()); std::copy(minString, minString + params.signatureSuffixLen, rec.dna + rec.minimizerPos); dnaChunk_.size += rec.len; } } else { for (uint32 j = 0; j < desc.recordsCount; ++j) { DnaRecord& rec = dnaBin_[recId++]; rec.dna = dnaBufferPtr + dnaChunk_.size; bool b = ReadNextRecord(metaReader, dnaReader, rec, settings); ASSERT(b); ASSERT(dnaChunk_.size + rec.len <= dnaChunk_.data.Size()); dnaChunk_.size += rec.len; } } metaReader.FlushInputWordBuffer(); dnaReader.FlushInputWordBuffer(); dnaBin_.SetStats(MIN(settings.minLen, dnaBin_.GetStats().minLen), MAX(settings.maxLen, dnaBin_.GetStats().maxLen)); ASSERT(metaReader.Position() - initialMetaPos == desc.metaSize); ASSERT(dnaReader.Position() - initialDnaPos == desc.dnaSize); } }
void DnaPacker::UnpackFromBin(const BinaryBinDescriptor& desc_, DnaBin &dnaBin_, DataChunk& dnaChunk_, BitMemoryReader& metaReader_, BitMemoryReader& dnaReader_, uint32 minimizerId_) { const uint64 recordsCount = desc_.recordsCount; const uint64 initialMetaPos = metaReader_.Position(); const uint64 initialDnaPos = dnaReader_.Position(); ASSERT(recordsCount < (1 << 28)); dnaBin_.Resize(recordsCount); // initialize settings // BinPackSettings settings; settings.minLen = metaReader_.GetBits(LenBits); settings.maxLen = metaReader_.GetBits(LenBits); settings.hasConstLen = (settings.minLen == settings.maxLen); ASSERT(settings.maxLen > 0); ASSERT(settings.maxLen >= settings.minLen); if (minimizerId_ != params.TotalMinimizersCount()) settings.suffixLen = params.signatureSuffixLen; else settings.suffixLen = 0; if (!settings.hasConstLen) { settings.bitsPerLen = bit_length(settings.maxLen - settings.minLen); ASSERT(settings.bitsPerLen > 0); } char* dnaBufferPtr = (char*)dnaChunk_.data.Pointer(); uint64 dnaBufferPos = 0; // unpack records // if (settings.suffixLen > 0) { char minString[64] = {0}; params.GenerateMinimizer(minimizerId_, minString); for (uint32 r = 0; r < recordsCount; ++r) { DnaRecord& rec = dnaBin_[r]; rec.dna = dnaBufferPtr + dnaChunk_.size + dnaBufferPos; bool b = ReadNextRecord(metaReader_, dnaReader_, rec, settings); ASSERT(b); ASSERT(dnaBufferPos + rec.len <= desc_.rawDnaSize); std::copy(minString, minString + params.signatureSuffixLen, rec.dna + rec.minimizerPos); dnaBufferPos += rec.len; } } else { for (uint32 r = 0; r < recordsCount; ++r) { DnaRecord& rec = dnaBin_[r]; rec.dna = dnaBufferPtr + dnaChunk_.size + dnaBufferPos; bool b = ReadNextRecord(metaReader_, dnaReader_, rec, settings); ASSERT(b); ASSERT(dnaBufferPos + rec.len <= desc_.rawDnaSize); dnaBufferPos += rec.len; } } dnaChunk_.size += dnaBufferPos; dnaBin_.SetStats(settings.minLen, settings.maxLen); metaReader_.FlushInputWordBuffer(); dnaReader_.FlushInputWordBuffer(); ASSERT(metaReader_.Position() - initialMetaPos == desc_.metaSize); ASSERT(dnaReader_.Position() - initialDnaPos == desc_.dnaSize); }