void Polynom::sub(const Polynom &o) // works as -= { if (o.size() > size()) { a.resize(o.size(), 0); } int sz = std::min(o.size(), size()); for (int i = 0; i < sz; i ++) a[i] -= o.get(i); }
Polynom polynomMultiply(const Polynom &p1, const Polynom &p2) { Polynom result; int i, j; Monom m; for (i = 0; i < p1.size(); ++i) for (j = 0; j < p2.size(); ++j) { m.xPow = p1.at(i).xPow + p2.at(j).xPow; m.yPow = p1.at(i).yPow + p2.at(j).yPow; m.c = p1.at(i).c * p2.at(j).c; addToPolynom(result, m); } return result; }
qreal polynomIntegral(const Polynom &p) { // all xPow's should be zero qreal result = 0; for (int i = 0; i < p.size(); ++i) result += p.at(i).c / (1 + p.at(i).yPow); return result; }
void addToPolynom(Polynom &p, const Monom &m) { for (int i = 0; i < p.size(); ++i) if (p.at(i).xPow == m.xPow && p.at(i).yPow == m.yPow) { p[i].c += m.c; return; } if (!qFuzzyIsNull(m.c)) p.append(m); }
Polynom add(const Polynom& rhs) const { Polynom res(std::max(rhs.degree(), degree())); std::copy(this->begin(), this->end(), res.begin()); for (size_t i = 0; i < rhs.size(); ++i) { res[i] += rhs[i]; } res.normalize(); return res; }
Polynom phiFunctionPolynom(const Triangle &triangle, QPointF vertex) { int n = 0; while (triangle[n] != vertex) ++n; double psiValue = psiFunction(vertex, triangle, n); Polynom result = psiFunctionPolynom(triangle, n); for (n = 0; n < result.size(); ++n) result[n].c /= psiValue; return result; }
Polynom multiply(const Polynom& rhs) const { Polynom res(rhs.degree() + degree()); for (size_t i = 0; i < this->size(); ++i) { for (size_t j = 0; j < rhs.size(); ++j) { res[i + j] += this->data()[i] * rhs[j]; } } res.normalize(); return res; }
void addToPolynom(Polynom &p, quint32 xPow, quint32 yPow, qreal c) { if (qFuzzyIsNull(c)) return; for (int i = 0; i < p.size(); ++i) if (p.at(i).xPow == xPow && p.at(i).yPow == yPow) { p[i].c += c; return; } Monom m; m.xPow = xPow; m.yPow = yPow; m.c = c; p.append(m); }
qreal getIntegralForGoodTriangle(QPointF * const triangle, const Polynom &polynom) { qreal transform[4]; transformateTriangle(triangle, transform); qreal newcx = transform[0] * triangle[2].x() + transform[2]; Polynom newPolynom, polynomPart1, polynomPart2, polynomBase; int i, j; for (i = 0; i < polynom.size(); ++i) { polynomPart1.clear(); polynomBase.clear(); addToPolynom(polynomBase, 1, 0, 1 / transform[0]); addToPolynom(polynomBase, 0, 0, -transform[2] / transform[0]); polynomPart1 = polynomPower(polynomBase, polynom.at(i).xPow); polynomPart2.clear(); polynomBase.clear(); addToPolynom(polynomBase, 0, 1, 1 / transform[1]); addToPolynom(polynomBase, 0, 0, -transform[3] / transform[1]); polynomPart2 = polynomPower(polynomBase, polynom.at(i).yPow); for (j = 0; j < polynomPart2.size(); ++j) polynomPart2[j].c *= polynom.at(i).c; newPolynom = polynomAdd(newPolynom, polynomMultiply(polynomPart1, polynomPart2)); } qreal result = 0; for (i = 0; i < newPolynom.size(); ++i) { polynomBase.clear(); addToPolynom(polynomBase, 0, 0, 1); addToPolynom(polynomBase, 0, 1, newcx - 1); polynomBase = polynomPower(polynomBase, newPolynom.at(i).xPow + 1); addToPolynom(polynomBase, 0, newPolynom.at(i).xPow + 1, qPow(newcx, newPolynom.at(i).xPow + 1)); for (j = 0; j < polynomBase.size(); ++j) { polynomBase[j].c /= newPolynom.at(i).xPow + 1; polynomBase[j].yPow += newPolynom.at(i).yPow; } result += newPolynom.at(i).c * polynomIntegral(polynomBase) / qAbs(transform[0] * transform[1]); } return result; }
IntervalledPolynom generateIntervalPartition(const unsigned int* const dimensional_upper_bounds, const size_t dimensions) { DEBUG_MSG("Interval Partitioning started"); // vektor<std::pair<vektor<unsigned int>, vektor<unsigned int> > solution; vektor<IB> intervalbounds; intervalbounds.push_back(dimensional_upper_bounds[0]); IntervalledPolynom intervalledPolynom; { Polynom pol(1); pol[0] = 1; intervalledPolynom.push_back(dimensional_upper_bounds[0], pol); } for(size_t k = 1; k < dimensions; ++k) { DEBUG_MSG("k: " << k); assert(dimensional_upper_bounds[k] > 0); vektor<IB> help_intervalbounds; help_intervalbounds.push_back(dimensional_upper_bounds[k] - 1); for(const IB& old_intervalbound : intervalbounds) help_intervalbounds.push_back(old_intervalbound + dimensional_upper_bounds[k]); vektor<IB> tmp_intervalbounds; IntervalledPolynom tmp_intervalledPolynom; for(size_t i = 0, j = 0, witness_left = 0, witness_right = 0, last_upper_bound_index = 0, last_lower_bound_index = 0; j < help_intervalbounds.size();) { const IB intervalbound = i < intervalbounds.size() ? intervalbounds[i] : 0; const IB help_intervalbound = help_intervalbounds[j]; const IB last_upper_bound = last_upper_bound_index == 0 ? 0 : (last_upper_bound_index > intervalbounds.size() ? intervalbounds[last_upper_bound_index-2] : intervalbounds[last_upper_bound_index-1]); const IB last_lower_bound = last_lower_bound_index == 0 ? 0 : (last_lower_bound_index > intervalbounds.size() ? intervalbounds[last_lower_bound_index-2] : intervalbounds[last_lower_bound_index-1]); DEBUG_MSG(""); DEBUG_MSG("k: " << k << ", i: " << i << ", j: " << j); if(i < intervalbounds.size()) { if(intervalbound < help_intervalbound) { tmp_intervalbounds.push_back(intervalbound); if(last_upper_bound < intervalbound) { ++witness_right; ++last_upper_bound_index; } if(intervalbound > last_lower_bound + dimensional_upper_bounds[k] ) //TODO: with else? { ++witness_left; ++last_lower_bound_index; } DEBUG_MSG("Fall 1, addiere " << intervalbound); // jetzt summe mit Anfangsintervall [..., // _old_intervals[j-1]] // und Endintervall [_old_intervals[i-1], ...]auswerten // Ergebnis zu _new_coefficients hinzufuegen ++i; } else if(intervalbound > help_intervalbound) { tmp_intervalbounds.push_back(help_intervalbound); if(last_upper_bound < help_intervalbound) { ++witness_right; ++last_upper_bound_index; } if(help_intervalbound > last_lower_bound + dimensional_upper_bounds[k]) { ++witness_left; ++last_lower_bound_index; } DEBUG_MSG("Fall 2, addiere " << help_intervalbound); // jetzt summe mit Anfangsintervall [..., // _old_intervals[j-1]] // und Endintervall [_old_intervals[i-1], // ...]auswerten // Ergebnis zu _new_coefficients hinzufuegen ++j; } else { tmp_intervalbounds.push_back(intervalbound); if(intervalbound > last_upper_bound) { ++witness_right; ++last_upper_bound_index; } if(intervalbound > last_lower_bound + dimensional_upper_bounds[k]) { ++witness_left; ++last_lower_bound_index; } DEBUG_MSG("Fall 3, addiere " << help_intervalbound); // jetzt summe mit Anfangsintervall [..., // _old_intervals[j-1]] // und Endintervall [_old_intervals[i-1], // ...]auswerten // Ergebnis zu _new_coefficients hinzufuegen ++i; ++j; } } else { tmp_intervalbounds.push_back(help_intervalbound); if(help_intervalbound > last_upper_bound && last_upper_bound_index <= intervalbounds.size()) { ++witness_right; ++last_upper_bound_index; } if(help_intervalbound > last_lower_bound + dimensional_upper_bounds[k]) { ++witness_left; ++last_lower_bound_index; } /* if(help_intervalbound <= static_cast<long>(intervalbounds[intervalbounds.size()-1])) { witness_right = intervalbounds.size(); ++witness_left; } else { if(witness_right == intervalbounds.size()) ++witness_right; else ++witness_left; } */ DEBUG_MSG("Fall 4, addiere " << help_intervalbound); // jetzt summe mit Anfangsintervall [..., // _old_intervals[j-1]] // und Endintervall [_old_intervals[i-1], ...]auswerten // Ergebnis zu _new_coefficients hinzufuegen ++j; } DEBUG_MSG("intervalledPolynom: " << intervalledPolynom); DEBUG_MSG("tmp_intervalledPolynom: " << tmp_intervalledPolynom); DEBUG_MSG("Witness: " << "[" << witness_left << ", " << witness_right << "]"); DEBUG_MSG("tmp_intervalbounds: " << tmp_intervalbounds); DEBUG_MSG("intervalbounds: " << intervalbounds); if(witness_left == witness_right) { if(witness_left <= intervalbounds.size() && witness_left > 0) { const IB& current_intervalbound = intervalbounds[witness_left-1]; //! DEBUG_MSG("Intervalbound: " << current_intervalbound); const Polynom& toSum = intervalledPolynom.at(current_intervalbound); const Polynom& upper = SumFromZeroToUpper::s(toSum); const Polynom lower = sumFromZeroToZMinusGamma(toSum, dimensional_upper_bounds[k]+1); Polynom together(std::max(upper.size(), lower.size())+1); for(size_t l = 0; l < together.size(); ++l) { if(l < upper.size()) together[l] += upper[l]; if(l < lower.size()) together[l] -= lower[l]; } DEBUG_MSG("Together Sum: " << together); tmp_intervalledPolynom.push_back(tmp_intervalbounds.back(), together); } else tmp_intervalledPolynom.push_back(tmp_intervalbounds.back(), Polynom::zero); } else { const Polynom lower_sum = (witness_left < 1 || witness_left-1 >= intervalbounds.size()) ? Polynom::zero : [&] () -> Polynom { const IB& lower_sum_intervalbound = intervalbounds[witness_left-1]; //! DEBUG_MSG("Lower Interval: " << lower_sum_intervalbound); return sumFromZMinusGammaToUpper(intervalledPolynom.at(lower_sum_intervalbound), dimensional_upper_bounds[k], lower_sum_intervalbound); }(); DEBUG_MSG("Lower Sum: " << lower_sum); const Z const_sum = ( (witness_left > 0 || witness_right > 0) && witness_right-witness_left > 1) ? [&] () -> Z { Q const_sumq; for(size_t constinterval = witness_left; constinterval <= witness_right-2; ++constinterval) { if(constinterval >= intervalbounds.size()) break; //! const IB& intervalupper_bound = intervalbounds[constinterval]; //! const Polynom& summedUp = SumFromZeroToUpper::s(intervalledPolynom.at(intervalupper_bound)); const_sumq += summedUp(intervalupper_bound); if(constinterval > 0) { const IB& intervallower_bound = intervalbounds[constinterval-1]; //! const_sumq -= summedUp(intervallower_bound); } } mpq_canonicalize(const_sumq.get_mpq_t()); assert(const_sumq.get_den() == 1); return const_sumq.get_num(); }() : 0; DEBUG_MSG("Constant Sum: " << const_sum); const Polynom upper_sum = (witness_right-1 >= intervalbounds.size()) ? Polynom::zero : [&] () -> Polynom { const IB& upper_sum_intervalupper_bound = intervalbounds[witness_right-1]; //! Polynom upper_sum_pol = SumFromZeroToUpper::s(intervalledPolynom.at(upper_sum_intervalupper_bound)); if(witness_right > 1) { const IB& upper_sum_intervallower_bound = intervalbounds[witness_right-2]; upper_sum_pol[0] -= upper_sum_pol(upper_sum_intervallower_bound); } DEBUG_MSG("Upper Interval: " << upper_sum_intervalupper_bound); return upper_sum_pol; }(); DEBUG_MSG("Upper Sum: " << upper_sum); Polynom together(std::max(upper_sum.size(), lower_sum.size())+1); for(size_t l = 0; l < together.size(); ++l) { if(l < lower_sum.size()) together[l] += lower_sum[l]; if(l < upper_sum.size()) together[l] += upper_sum[l]; } together[0] += const_sum; DEBUG_MSG("Together Sum: " << together); tmp_intervalledPolynom.push_back(tmp_intervalbounds.back(), together); } } intervalbounds.swap(tmp_intervalbounds); intervalledPolynom.swap(tmp_intervalledPolynom); DEBUG_MSG("_old_intervals: " << intervalbounds); } DEBUG_MSG("Resulting Intervalled Polynom: " << intervalledPolynom); return intervalledPolynom; }
Polynom polynomAdd(const Polynom &p1, const Polynom &p2) { Polynom result = p1; for (int i = 0; i < p2.size(); ++i) addToPolynom(result, p2.at(i)); return result; }