1 #ifndef _URATIONALFUNCTION_H_ 2 #define _URATIONALFUNCTION_H_ 6 #include "../polynomial.h" 7 #include "rationalfunction_euclideanmethods.h" 8 #include "rationalfunction_symbolicintegration.h" 9 #include "multiprecision_rootfinding.h" 10 #include "rationalfunction_integrationpostprocessing.h" 11 #include "rationalfunction_symbolicnumericintegration.h" 12 #include "rationalfunction_integrationprinting.h" 13 #include "rationalfunction_complexrationalnumberordering.h" 20 bool operator()(
const IntegralTerm a,
const IntegralTerm b)
const {
21 if (a.Sindex > b.Sindex)
23 else if (a.Sindex < b.Sindex)
26 if (a.tindex > b.tindex)
33 bool operator<(
const IntegralTerm b)
const {
34 if (this->Sindex < b.Sindex)
36 else if (this->Sindex > b.Sindex)
39 if (this->tindex < b.tindex)
46 inline friend std::ostream& operator<< (std::ostream &out, IntegralTerm b) {
47 out <<
"[" << b.Sindex <<
"," << b.tindex <<
"]";
57 typedef std::map<int, IntegralTerm> RootIntegralTermMap;
58 typedef RootIntegralTermMap::const_iterator RITMIter;
59 typedef std::multimap<IntegralTerm, int> IntegralTermRootMap;
60 typedef IntegralTermRootMap::const_iterator ITRMIter;
61 typedef std::multimap<ComplexRationalNumber, int, CompareByRealThenReverseImaginary> residueRootIndexMap;
62 typedef residueRootIndexMap::const_iterator RRIMIter;
63 typedef std::multimap<int, int> TermRootMap;
64 typedef TermRootMap::const_iterator TRMIter;
71 template <
class UnivariatePolynomialOverField,
class Field>
73 private Derived_from<Field,BPASField<Field>> {
75 UnivariatePolynomialOverField den;
76 UnivariatePolynomialOverField num;
81 bool floatingPointPrinting;
82 std::string outputFormatting;
84 inline void normalize () {
85 num /= den.leadingCoefficient();
86 den /= den.leadingCoefficient();
89 mpz_class characteristic;
90 static bool isPrimeField;
91 static bool isSmallPrimeField;
92 static bool isComplexField;
102 ERROR_ANALYSIS =
false;
103 PFD_LOG_PART =
false;
104 floatingPointPrinting =
false;
105 outputFormatting =
"MAPLE_OUTPUT";
106 UnivariatePolynomialOverField e;
107 characteristic = e.characteristic;
116 ERROR_ANALYSIS(b.ERROR_ANALYSIS), PFD_LOG_PART(b.PFD_LOG_PART), floatingPointPrinting(b.floatingPointPrinting), outputFormatting(b.outputFormatting) {
117 characteristic = b.characteristic;
126 if (a.variable() != b.variable()) {
127 std::cout <<
"BPAS error: numerator and denominator must have the same variable." << std::endl;
131 std::cout <<
"BPAS error: denominator is zero from UnivariateRationalFunction<UnivariatePolynomialOverField,Field>" << std::endl;
137 ERROR_ANALYSIS =
false;
138 PFD_LOG_PART =
false;
139 floatingPointPrinting =
false;
140 UnivariatePolynomialOverField e;
141 characteristic = e.characteristic;
142 outputFormatting =
"MAPLE_OUTPUT";
152 inline void setVariableName(
Symbol name) {
153 num.setVariableName(name);
154 den.setVariableName(name);
157 inline Symbol variable() {
158 return num.variable();
161 inline bool isProfiling() {
165 inline void setProfiling(
bool a) {
169 inline bool isAnalyzingError() {
170 return ERROR_ANALYSIS;
173 inline void setAnalyzingError(
bool a) {
177 inline bool isPFDLogPart() {
181 inline void setPFDLogPart(
bool a) {
185 inline bool isFloatingPointPrinting() {
186 return floatingPointPrinting;
189 inline void setFloatingPointPrinting(
bool a) {
190 floatingPointPrinting = a;
193 inline bool isMapleOutput() {
194 if (outputFormatting ==
"MAPLE_OUTPUT")
200 inline void setMapleOutput() {
201 outputFormatting =
"MAPLE_OUTPUT";
204 inline bool isMatlabOutput() {
205 if (outputFormatting ==
"MATLAB_OUTPUT")
211 inline void setMatlabOutput() {
212 outputFormatting =
"MATLAB_OUTPUT";
215 inline void setNumerator(
const UnivariatePolynomialOverField& b) {
216 if (num.variable() != b.variable()) {
217 std::cout <<
"BPAS error: numerator and denominator must have the same variable." << std::endl;
224 inline void setDenominator(
const UnivariatePolynomialOverField& b) {
225 if (num.variable() != b.variable()) {
226 std::cout <<
"BPAS error: numerator and denominator must have the same variable." << std::endl;
233 inline void set(
const UnivariatePolynomialOverField& a,
const UnivariatePolynomialOverField& b) {
234 if (a.variable() != b.variable()) {
235 std::cout <<
"BPAS error: numerator and denominator must have the same variable." << std::endl;
243 inline UnivariatePolynomialOverField
numerator()
const {
251 inline Field evaluate(
const Field& c) {
253 output = num.evaluate(c);
254 output /= den.evaluate(c);
259 return (!(num == b.num) || !(den == b.den));
262 return ((num == b.num) && (den == b.den));
270 if (num.variable()!= b.num.variable()) {
271 std::cout <<
"BPAS: error, trying to add between RationalFunction[" << num.variable() <<
"] and RationalFunction[" << b.num.variable() <<
"]." << std::endl;
274 UnivariatePolynomialOverField g, r1(den), r2(b.den);
297 if (num.variable()!= b.num.variable()) {
298 std::cout <<
"BPAS: error, trying to subtract between RationalFunction[" << num.variable() <<
"] and RationalFunction[" << b.num.variable() <<
"]." << std::endl;
301 UnivariatePolynomialOverField g, r1(den), r2(b.den);
332 res.setVariableName(num.variable());
333 if (isZero() || isOne() || e == 1)
342 if (e % 2) { res *= x; }
368 std::cout <<
"BPAS error: division by zero from UnivariateRationalFunction<UnivariatePolynomialOverField,Field> inverse()" << std::endl;
381 if (num.variable()!= b.num.variable()) {
382 std::cout <<
"BPAS: error, trying to multiply between RationalFunction[" << num.variable() <<
"] and RationalFunction[" << b.num.variable() <<
"]." << std::endl;
386 UnivariatePolynomialOverField g1, g2, r;
405 std::cout <<
"BPAS error: division by zero from UnivariateRationalFunction<UnivariatePolynomialOverField,Field> operator/=" << std::endl;
409 if (num.variable()!= b.num.variable()) {
410 std::cout <<
"BPAS: error, trying to divide between RationalFunction[" << num.variable() <<
"] and RationalFunction[" << b.num.variable() <<
"]." << std::endl;
419 UnivariatePolynomialOverField temp;
423 num /= den.leadingCoefficient();
424 den /= den.leadingCoefficient();
438 return num.isOne() && den.isOne();
444 inline bool isNegativeOne()
const {
445 return (num.isNegativeOne() && den.isOne()) || (num.isOne() && den.isNegativeOne());
447 inline void negativeOne() {
451 inline int isConstant()
const {
452 return num.isConstant() && den.isConstant();
456 UnivariatePolynomialOverField du,dc,dv,g,temp;
459 dc = temp.unitCanonical(&du,&dv);
464 if (u != NULL || v!= NULL) {
487 characteristic = b.characteristic;
493 std::cerr <<
"UnivariateRationalFunction::convertToExpressionTree NOT YET IMPLEMENTED" << std::endl;
504 void print(std::ostream& ostream)
const {
505 ostream <<
"(" << num <<
")/(" << den <<
")";
535 std::cerr <<
"UnivariateRationalFunction::gcd NOT YET IMPLEMENTED" << std::endl;
544 std::cerr <<
"UnivariateRationalFunction::squareFree NOT YET IMPLEMENTED" << std::endl;
546 std::vector<UnivariateRationalFunction> ret;
547 ret.push_back(*
this);
552 std::cerr <<
"UnivariateRationalFunction::euclideanSize NOT YET IMPLEMENTED" << std::endl;
560 std::cerr <<
"UnivariateRationalFunction::euclideanDivision NOT YET IMPLEMENTED" << std::endl;
577 std::cerr <<
"UnivariateRationalFunction::extendedEuclidean NOT YET IMPLEMENTED" << std::endl;
588 *
this = this->remainder(b);
593 std::vector<UnivariatePolynomialOverField> gg,hh;
596 temp.setVariableName(num.variable());
597 h->setVariableName(num.variable());
599 _hermiteReduce<UnivariatePolynomialOverField,Field>(num,den,&gg,&hh);
601 while (i<gg.size()) {
602 temp.set(gg.at(i),gg.at(i+1));
606 temp.set(hh.at(0),hh.at(1));
614 _integrateRationalFunctionLogPart<UnivariatePolynomialOverField,Field>(S,U,num,den,PROFILING);
617 void differentiate() {
622 UnivariatePolynomialOverField D(den);
623 UnivariatePolynomialOverField dD(den);
624 UnivariatePolynomialOverField temp;
659 std::vector<UnivariatePolynomialOverField> G;
661 temp.setVariableName(num.variable());
664 unsigned long long start;
668 std::cout <<
"integrate" << std::endl;
669 std::cout <<
"--------------------------------------" << std::endl;
673 _integrateRationalFunction<UnivariatePolynomialOverField,Field>(num,den,P,&G,U,S,PROFILING);
676 stopTimer(&start,&elapsed);
677 std::cout <<
"--------------------------------------" << std::endl;
678 std::cout <<
"integrate runtime: " << elapsed <<
" s" << std::endl;
683 temp.set(G.at(i),G.at(i+1));
697 std::vector<UnivariatePolynomialOverField> G;
699 temp.setVariableName(num.variable());
701 std::cout <<
"[realSymbolicNumericIntegrate (snInt): Symbolic-Numeric Integration with BPAS and MPSolve]" << std::endl;
702 std::cout <<
"[Integration method: Hermite reduction, LRT integration]" << std::endl;
703 std::cout <<
"Starting..." << std::endl;
706 unsigned long long start;
710 std::cout <<
"--------------------------------------" << std::endl;
714 _realSNIntegrate<UnivariatePolynomialOverField,Field>(num,den,P,&G,lg,Lg,atn,Atn,prec,PROFILING,PFD_LOG_PART,ERROR_ANALYSIS);
717 stopTimer(&start,&elapsed);
718 std::cout <<
"--------------------------------------" << std::endl;
719 std::cout <<
"realSymbolicNumericIntegrate runtime: " << elapsed <<
" s" << std::endl;
721 fs.open(
"perftiming.txt",std::fstream::in | std::fstream::out | std::fstream::app);
722 fs << elapsed << std::endl;
728 temp.set(G.at(i),G.at(i+1));
735 void realSymbolicNumericIntegrate(UnivariatePolynomialOverField *P, std::vector<
UnivariateRationalFunction<UnivariatePolynomialOverField,Field> > *g, std::vector<Field> *lg, std::vector<UnivariatePolynomialOverField> *Lg, std::vector<Field> *atn, std::vector<UnivariatePolynomialOverField> *Atn1, std::vector<UnivariatePolynomialOverField> *Atn2,
int prec) {
743 std::vector<UnivariatePolynomialOverField> G;
745 temp.setVariableName(num.variable());
747 std::cout <<
"[realSymbolicNumericIntegrate (snInt): Symbolic-Numeric Integration with BPAS and MPSolve]" << std::endl;
748 std::cout <<
"[Integration method: Hermite reduction, LRT integration]" << std::endl;
749 std::cout <<
"Starting..." << std::endl;
752 unsigned long long start;
756 std::cout <<
"--------------------------------------" << std::endl;
760 _realSNIntegrate<UnivariatePolynomialOverField,Field>(num,den,P,&G,lg,Lg,atn,Atn1,Atn2,prec,PROFILING,PFD_LOG_PART,ERROR_ANALYSIS);
763 stopTimer(&start,&elapsed);
764 std::cout <<
"--------------------------------------" << std::endl;
765 std::cout <<
"realSymbolicNumericIntegrate runtime: " << elapsed <<
" s" << std::endl;
767 fs.open(
"perftiming.txt",std::fstream::in | std::fstream::out | std::fstream::app);
768 fs << elapsed << std::endl;
774 temp.set(G.at(i),G.at(i+1));
781 void realSymbolicNumericIntegratePFD(UnivariatePolynomialOverField *P, std::vector<
UnivariateRationalFunction<UnivariatePolynomialOverField,Field> > *g, std::vector<Field> *lg, std::vector<UnivariatePolynomialOverField> *Lg, std::vector<Field> *atn, std::vector<UnivariatePolynomialOverField> *Atn,
int prec) {
788 std::vector<UnivariatePolynomialOverField> G;
790 temp.setVariableName(num.variable());
792 std::cout <<
"[realSymbolicNumericIntegratePFD (snIntPFD): Symbolic-Numeric Integration with BPAS and MPSolve]" << std::endl;
793 std::cout <<
"[Integration method: Hermite reduction, PFD integration]" << std::endl;
794 std::cout <<
"Starting..." << std::endl;
797 unsigned long long start;
801 std::cout <<
"--------------------------------------" << std::endl;
805 _realSNIntegratePFD<UnivariatePolynomialOverField,Field>(num,den,P,&G,lg,Lg,atn,Atn,prec,PROFILING,PFD_LOG_PART,ERROR_ANALYSIS);
808 stopTimer(&start,&elapsed);
809 std::cout <<
"--------------------------------------" << std::endl;
810 std::cout <<
"realSymbolicNumericIntegratePFD runtime: " << elapsed <<
" s" << std::endl;
812 fs.open(
"perftiming.txt",std::fstream::in | std::fstream::out | std::fstream::app);
813 fs << elapsed << std::endl;
819 temp.set(G.at(i),G.at(i+1));
826 void realSymbolicNumericIntegrateSimplePFD(UnivariatePolynomialOverField *P, std::vector<
UnivariateRationalFunction<UnivariatePolynomialOverField,Field> > *g, std::vector<Field> *lg, std::vector<UnivariatePolynomialOverField> *Lg, std::vector<Field> *atn, std::vector<UnivariatePolynomialOverField> *Atn,
int prec) {
833 std::vector<UnivariatePolynomialOverField> G;
835 temp.setVariableName(num.variable());
837 std::cout <<
"[realSymbolicNumericIntegratePFD (snIntPFD): Symbolic-Numeric Integration with BPAS and MPSolve]" << std::endl;
838 std::cout <<
"[Integration method: Hermite reduction, PFD integration]" << std::endl;
839 std::cout <<
"Starting..." << std::endl;
842 unsigned long long start;
846 std::cout <<
"--------------------------------------" << std::endl;
850 _realSNIntegrateSimplePFD<UnivariatePolynomialOverField,Field>(num,den,P,&G,lg,Lg,atn,Atn,prec,PROFILING,PFD_LOG_PART,ERROR_ANALYSIS);
853 stopTimer(&start,&elapsed);
854 std::cout <<
"--------------------------------------" << std::endl;
855 std::cout <<
"realSymbolicNumericIntegratePFD runtime: " << elapsed <<
" s" << std::endl;
857 fs.open(
"perftiming.txt",std::fstream::in | std::fstream::out | std::fstream::app);
858 fs << elapsed << std::endl;
864 temp.set(G.at(i),G.at(i+1));
914 std::vector<UnivariatePolynomialOverField> G;
915 for (
int i=0; i<g.size(); i++) {
916 G.push_back(g.at(i).num);
917 G.push_back(g.at(i).den);
919 _printFormalIntegral<UnivariatePolynomialOverField,Field>(num,den,P,G,U,S,
false, floatingPointPrinting,
false);
923 std::vector<UnivariatePolynomialOverField> G;
924 for (
int i=0; i<g.size(); i++) {
925 G.push_back(g.at(i).num);
926 G.push_back(g.at(i).den);
928 std::vector<UnivariatePolynomialOverField> empty;
929 _printIntegral<UnivariatePolynomialOverField,Field>(num,den,P,G,lg,Lg,atn,Atn,empty,
false, floatingPointPrinting,
false, outputFormatting);
932 void printIntegral(UnivariatePolynomialOverField &P, std::vector<
UnivariateRationalFunction<UnivariatePolynomialOverField,Field> > &g, std::vector<Field> &lg, std::vector<UnivariatePolynomialOverField> &Lg, std::vector<Field> &atn, std::vector<UnivariatePolynomialOverField> &Atn1, std::vector<UnivariatePolynomialOverField> &Atn2){
933 std::vector<UnivariatePolynomialOverField> G;
934 for (
int i=0; i<g.size(); i++) {
935 G.push_back(g.at(i).num);
936 G.push_back(g.at(i).den);
938 _printIntegral<UnivariatePolynomialOverField,Field>(num,den,P,G,lg,Lg,atn,Atn1,Atn2,
false, floatingPointPrinting,
false, outputFormatting);
941 void realSymbolicNumericIntegrate(
int prec) {
942 UnivariatePolynomialOverField P;
943 std::vector< UnivariateRationalFunction<UnivariatePolynomialOverField,Field> > g;
944 std::vector<Field> lg, atn;
945 std::vector<UnivariatePolynomialOverField> Lg, Atn1, Atn2;
947 realSymbolicNumericIntegrate(&P, &g, &lg, &Lg, &atn, &Atn1, &Atn2, prec);
948 printIntegral(P, g, lg, Lg, atn, Atn1, Atn2);
952 UnivariatePolynomialOverField P;
953 std::vector< UnivariateRationalFunction<UnivariatePolynomialOverField,Field> > g;
954 std::vector<UnivariatePolynomialOverField> U;
955 std::vector< SparseUnivariatePolynomial<UnivariatePolynomialOverField> > S;
957 integrate(&P, &g, &U, &S);
958 printIntegral(P, g, U, S);
UnivariateRationalFunction< UnivariatePolynomialOverField, Field > remainder(const UnivariateRationalFunction< UnivariatePolynomialOverField, Field > &b) const
Get the remainder of *this and b.
Definition: urationalfunction.h:570
UnivariateRationalFunction< UnivariatePolynomialOverField, Field > unitCanonical(UnivariateRationalFunction< UnivariatePolynomialOverField, Field > *u=NULL, UnivariateRationalFunction< UnivariatePolynomialOverField, Field > *v=NULL) const
Obtain the unit normal (a.k.a canonical associate) of an element.
Definition: urationalfunction.h:455
A univariate polynomial over an arbitrary BPASRing represented sparsely.
Definition: BigPrimeField.hpp:21
void canonicalize()
Canonicalize this fraction, reducing terms as needed.
Definition: urationalfunction.h:418
UnivariateRationalFunction< UnivariatePolynomialOverField, Field > euclideanSize() const
Get the euclidean size of *this.
Definition: urationalfunction.h:551
An abstract class defining the interface of a rational function.
Definition: polynomial.h:186
An ExpressionTree encompasses various forms of data that can be expressed generically as a binary tre...
Definition: ExpressionTree.hpp:17
UnivariatePolynomialOverField numerator() const
Get the fraction's numerator.
Definition: urationalfunction.h:243
void print(std::ostream &ostream) const
Overload stream operator <<.
Definition: urationalfunction.h:504
ExpressionTree convertToExpressionTree() const
Convert this to an expression tree.
Definition: urationalfunction.h:492
UnivariateRationalFunction< UnivariatePolynomialOverField, Field > & operator%=(const UnivariateRationalFunction< UnivariatePolynomialOverField, Field > &b)
Assign *this to be the remainder of *this and b.
Definition: urationalfunction.h:587
UnivariateRationalFunction< UnivariatePolynomialOverField, Field > operator%(const UnivariateRationalFunction< UnivariatePolynomialOverField, Field > &b) const
Get the remainder of *this and b;.
Definition: urationalfunction.h:582
void zero()
Make *this ring element zero.
Definition: urationalfunction.h:433
A simple data structure for encapsulating a collection of Factor elements.
Definition: Factors.hpp:95
UnivariateRationalFunction< UnivariatePolynomialOverField, Field > gcd(const UnivariateRationalFunction< UnivariatePolynomialOverField, Field > &b) const
BPASGCDDomain, BPASEuclideanDomain, BPASField virtual methods.
Definition: urationalfunction.h:534
UnivariatePolynomialOverField denominator() const
Get the fraction's denominator.
Definition: urationalfunction.h:247
UnivariateRationalFunction< UnivariatePolynomialOverField, Field > inverse() const
Get the inverse of *this.
Definition: urationalfunction.h:366
UnivariateRationalFunction< UnivariatePolynomialOverField, Field > quotient(const UnivariateRationalFunction< UnivariatePolynomialOverField, Field > &b) const
Get the quotient of *this and b.
Definition: urationalfunction.h:566
void one()
Make *this ring element one.
Definition: urationalfunction.h:440
UnivariateRationalFunction< UnivariatePolynomialOverField, Field > extendedEuclidean(const UnivariateRationalFunction< UnivariatePolynomialOverField, Field > &b, UnivariateRationalFunction< UnivariatePolynomialOverField, Field > *s=NULL, UnivariateRationalFunction< UnivariatePolynomialOverField, Field > *t=NULL) const
Perofrm the extended euclidean division on *this and b.
Definition: urationalfunction.h:574
bool isZero() const
Determine if *this ring element is zero, that is the additive identity.
Definition: urationalfunction.h:430
A univariate rational function templated by a unvariate polynomial over a field.
Definition: urationalfunction.h:72
An encapsulation of a mathematical symbol.
Definition: Symbol.hpp:23
bool isOne() const
Determine if *this ring element is one, that is the multiplication identity.
Definition: urationalfunction.h:437
UnivariateRationalFunction< UnivariatePolynomialOverField, Field > euclideanDivision(const UnivariateRationalFunction< UnivariatePolynomialOverField, Field > &b, UnivariateRationalFunction< UnivariatePolynomialOverField, Field > *q=NULL) const
Perform the eucldiean division of *this and b.
Definition: urationalfunction.h:558
Factors< UnivariateRationalFunction > squareFree() const
Compute squarefree factorization of *this.
Definition: urationalfunction.h:543