1 #ifndef _URATIONALFUNCTION_H_ 2 #define _URATIONALFUNCTION_H_ 6 #include "BPASRationalFunction.hpp" 7 #include "../RingPolynomial/upolynomial.h" 8 #include "rationalfunction_euclideanmethods.h" 9 #include "rationalfunction_symbolicintegration.h" 10 #include "multiprecision_rootfinding.h" 11 #include "rationalfunction_integrationpostprocessing.h" 12 #include "rationalfunction_symbolicnumericintegration.h" 13 #include "rationalfunction_integrationprinting.h" 14 #include "rationalfunction_complexrationalnumberordering.h" 21 bool operator()(
const IntegralTerm a,
const IntegralTerm b)
const {
22 if (a.Sindex > b.Sindex)
24 else if (a.Sindex < b.Sindex)
27 if (a.tindex > b.tindex)
34 bool operator<(
const IntegralTerm b)
const {
35 if (this->Sindex < b.Sindex)
37 else if (this->Sindex > b.Sindex)
40 if (this->tindex < b.tindex)
47 inline friend std::ostream& operator<< (std::ostream &out, IntegralTerm b) {
48 out <<
"[" << b.Sindex <<
"," << b.tindex <<
"]";
58 typedef std::map<int, IntegralTerm> RootIntegralTermMap;
59 typedef RootIntegralTermMap::const_iterator RITMIter;
60 typedef std::multimap<IntegralTerm, int> IntegralTermRootMap;
61 typedef IntegralTermRootMap::const_iterator ITRMIter;
62 typedef std::multimap<ComplexRationalNumber, int, CompareByRealThenReverseImaginary> residueRootIndexMap;
63 typedef residueRootIndexMap::const_iterator RRIMIter;
64 typedef std::multimap<int, int> TermRootMap;
65 typedef TermRootMap::const_iterator TRMIter;
72 template <
class UnivariatePolynomialOverField,
class Field>
74 private Derived_from<Field,BPASField<Field>> {
76 UnivariatePolynomialOverField den;
77 UnivariatePolynomialOverField num;
82 bool floatingPointPrinting;
83 std::string outputFormatting;
85 inline void normalize () {
86 num /= den.leadingCoefficient();
87 den /= den.leadingCoefficient();
90 mpz_class characteristic;
91 static bool isPrimeField;
92 static bool isSmallPrimeField;
93 static bool isComplexField;
103 ERROR_ANALYSIS =
false;
104 PFD_LOG_PART =
false;
105 floatingPointPrinting =
false;
106 outputFormatting =
"MAPLE_OUTPUT";
107 UnivariatePolynomialOverField e;
108 characteristic = e.getCharacteristic();
117 ERROR_ANALYSIS(b.ERROR_ANALYSIS), PFD_LOG_PART(b.PFD_LOG_PART), floatingPointPrinting(b.floatingPointPrinting), outputFormatting(b.outputFormatting) {
118 characteristic = b.characteristic;
127 if (a.variable() != b.variable()) {
128 std::cout <<
"BPAS error: numerator and denominator must have the same variable." << std::endl;
132 std::cout <<
"BPAS error: denominator is zero from UnivariateRationalFunction<UnivariatePolynomialOverField,Field>" << std::endl;
138 ERROR_ANALYSIS =
false;
139 PFD_LOG_PART =
false;
140 floatingPointPrinting =
false;
141 UnivariatePolynomialOverField e;
142 characteristic = e.getCharacteristic();
143 outputFormatting =
"MAPLE_OUTPUT";
153 inline void setVariableName(
Symbol name) {
154 num.setVariableName(name);
155 den.setVariableName(name);
158 inline Symbol variable() {
159 return num.variable();
162 inline bool isProfiling() {
166 inline void setProfiling(
bool a) {
170 inline bool isAnalyzingError() {
171 return ERROR_ANALYSIS;
174 inline void setAnalyzingError(
bool a) {
178 inline bool isPFDLogPart() {
182 inline void setPFDLogPart(
bool a) {
186 inline bool isFloatingPointPrinting() {
187 return floatingPointPrinting;
190 inline void setFloatingPointPrinting(
bool a) {
191 floatingPointPrinting = a;
194 inline bool isMapleOutput() {
195 if (outputFormatting ==
"MAPLE_OUTPUT")
201 inline void setMapleOutput() {
202 outputFormatting =
"MAPLE_OUTPUT";
205 inline bool isMatlabOutput() {
206 if (outputFormatting ==
"MATLAB_OUTPUT")
212 inline void setMatlabOutput() {
213 outputFormatting =
"MATLAB_OUTPUT";
216 inline void setNumerator(
const UnivariatePolynomialOverField& b) {
217 if (num.variable() != b.variable()) {
218 std::cout <<
"BPAS error: numerator and denominator must have the same variable." << std::endl;
225 inline void setDenominator(
const UnivariatePolynomialOverField& b) {
226 if (num.variable() != b.variable()) {
227 std::cout <<
"BPAS error: numerator and denominator must have the same variable." << std::endl;
234 inline void set(
const UnivariatePolynomialOverField& a,
const UnivariatePolynomialOverField& b) {
235 if (a.variable() != b.variable()) {
236 std::cout <<
"BPAS error: numerator and denominator must have the same variable." << std::endl;
244 inline UnivariatePolynomialOverField
numerator()
const {
252 inline Field evaluate(
const Field& c) {
254 output = num.evaluate(c);
255 output /= den.evaluate(c);
260 return (!(num == b.num) || !(den == b.den));
263 return ((num == b.num) && (den == b.den));
271 if (num.variable()!= b.num.variable()) {
272 std::cout <<
"BPAS: error, trying to add between RationalFunction[" << num.variable() <<
"] and RationalFunction[" << b.num.variable() <<
"]." << std::endl;
275 UnivariatePolynomialOverField g, r1(den), r2(b.den);
298 if (num.variable()!= b.num.variable()) {
299 std::cout <<
"BPAS: error, trying to subtract between RationalFunction[" << num.variable() <<
"] and RationalFunction[" << b.num.variable() <<
"]." << std::endl;
302 UnivariatePolynomialOverField g, r1(den), r2(b.den);
333 res.setVariableName(num.variable());
334 if (isZero() || isOne() || e == 1)
343 if (e % 2) { res *= x; }
369 std::cout <<
"BPAS error: division by zero from UnivariateRationalFunction<UnivariatePolynomialOverField,Field> inverse()" << std::endl;
382 if (num.variable()!= b.num.variable()) {
383 std::cout <<
"BPAS: error, trying to multiply between RationalFunction[" << num.variable() <<
"] and RationalFunction[" << b.num.variable() <<
"]." << std::endl;
387 UnivariatePolynomialOverField g1, g2, r;
406 std::cout <<
"BPAS error: division by zero from UnivariateRationalFunction<UnivariatePolynomialOverField,Field> operator/=" << std::endl;
410 if (num.variable()!= b.num.variable()) {
411 std::cout <<
"BPAS: error, trying to divide between RationalFunction[" << num.variable() <<
"] and RationalFunction[" << b.num.variable() <<
"]." << std::endl;
420 UnivariatePolynomialOverField temp;
424 num /= den.leadingCoefficient();
425 den /= den.leadingCoefficient();
439 return num.isOne() && den.isOne();
445 inline bool isNegativeOne()
const {
446 return (num.isNegativeOne() && den.isOne()) || (num.isOne() && den.isNegativeOne());
448 inline void negativeOne() {
452 inline int isConstant()
const {
453 return num.isConstant() && den.isConstant();
457 UnivariatePolynomialOverField du,dc,dv,g,temp;
460 dc = temp.unitCanonical(&du,&dv);
465 if (u != NULL || v!= NULL) {
488 characteristic = b.characteristic;
494 std::cerr <<
"UnivariateRationalFunction::convertToExpressionTree NOT YET IMPLEMENTED" << std::endl;
505 void print(std::ostream& ostream)
const {
506 ostream <<
"(" << num <<
")/(" << den <<
")";
536 std::cerr <<
"UnivariateRationalFunction::gcd NOT YET IMPLEMENTED" << std::endl;
545 std::cerr <<
"UnivariateRationalFunction::squareFree NOT YET IMPLEMENTED" << std::endl;
547 std::vector<UnivariateRationalFunction> ret;
548 ret.push_back(*
this);
558 std::cerr <<
"UnivariateRationalFunction::euclideanDivision NOT YET IMPLEMENTED" << std::endl;
575 std::cerr <<
"UnivariateRationalFunction::extendedEuclidean NOT YET IMPLEMENTED" << std::endl;
586 *
this = this->remainder(b);
592 std::vector<UnivariatePolynomialOverField> gg,hh;
595 temp.setVariableName(num.variable());
596 h->setVariableName(num.variable());
598 _hermiteReduce<UnivariatePolynomialOverField,Field>(num,den,&gg,&hh);
600 while (i<gg.size()) {
601 temp.set(gg.at(i),gg.at(i+1));
605 temp.set(hh.at(0),hh.at(1));
613 _integrateRationalFunctionLogPart<UnivariatePolynomialOverField,Field>(S,U,num,den,PROFILING);
616 void differentiate() {
621 UnivariatePolynomialOverField D(den);
622 UnivariatePolynomialOverField dD(den);
623 UnivariatePolynomialOverField temp;
658 std::vector<UnivariatePolynomialOverField> G;
660 temp.setVariableName(num.variable());
663 unsigned long long start;
667 std::cout <<
"integrate" << std::endl;
668 std::cout <<
"--------------------------------------" << std::endl;
672 _integrateRationalFunction<UnivariatePolynomialOverField,Field>(num,den,P,&G,U,S,PROFILING);
675 stopTimer(&start,&elapsed);
676 std::cout <<
"--------------------------------------" << std::endl;
677 std::cout <<
"integrate runtime: " << elapsed <<
" s" << std::endl;
682 temp.set(G.at(i),G.at(i+1));
696 std::vector<UnivariatePolynomialOverField> G;
698 temp.setVariableName(num.variable());
700 std::cout <<
"[realSymbolicNumericIntegrate (snInt): Symbolic-Numeric Integration with BPAS and MPSolve]" << std::endl;
701 std::cout <<
"[Integration method: Hermite reduction, LRT integration]" << std::endl;
702 std::cout <<
"Starting..." << std::endl;
705 unsigned long long start;
709 std::cout <<
"--------------------------------------" << std::endl;
713 _realSNIntegrate<UnivariatePolynomialOverField,Field>(num,den,P,&G,lg,Lg,atn,Atn,prec,PROFILING,PFD_LOG_PART,ERROR_ANALYSIS);
716 stopTimer(&start,&elapsed);
717 std::cout <<
"--------------------------------------" << std::endl;
718 std::cout <<
"realSymbolicNumericIntegrate runtime: " << elapsed <<
" s" << std::endl;
720 fs.open(
"perftiming.txt",std::fstream::in | std::fstream::out | std::fstream::app);
721 fs << elapsed << std::endl;
727 temp.set(G.at(i),G.at(i+1));
734 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) {
742 std::vector<UnivariatePolynomialOverField> G;
744 temp.setVariableName(num.variable());
746 std::cout <<
"[realSymbolicNumericIntegrate (snInt): Symbolic-Numeric Integration with BPAS and MPSolve]" << std::endl;
747 std::cout <<
"[Integration method: Hermite reduction, LRT integration]" << std::endl;
748 std::cout <<
"Starting..." << std::endl;
751 unsigned long long start;
755 std::cout <<
"--------------------------------------" << std::endl;
759 _realSNIntegrate<UnivariatePolynomialOverField,Field>(num,den,P,&G,lg,Lg,atn,Atn1,Atn2,prec,PROFILING,PFD_LOG_PART,ERROR_ANALYSIS);
762 stopTimer(&start,&elapsed);
763 std::cout <<
"--------------------------------------" << std::endl;
764 std::cout <<
"realSymbolicNumericIntegrate runtime: " << elapsed <<
" s" << std::endl;
766 fs.open(
"perftiming.txt",std::fstream::in | std::fstream::out | std::fstream::app);
767 fs << elapsed << std::endl;
773 temp.set(G.at(i),G.at(i+1));
780 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) {
787 std::vector<UnivariatePolynomialOverField> G;
789 temp.setVariableName(num.variable());
791 std::cout <<
"[realSymbolicNumericIntegratePFD (snIntPFD): Symbolic-Numeric Integration with BPAS and MPSolve]" << std::endl;
792 std::cout <<
"[Integration method: Hermite reduction, PFD integration]" << std::endl;
793 std::cout <<
"Starting..." << std::endl;
796 unsigned long long start;
800 std::cout <<
"--------------------------------------" << std::endl;
804 _realSNIntegratePFD<UnivariatePolynomialOverField,Field>(num,den,P,&G,lg,Lg,atn,Atn,prec,PROFILING,PFD_LOG_PART,ERROR_ANALYSIS);
807 stopTimer(&start,&elapsed);
808 std::cout <<
"--------------------------------------" << std::endl;
809 std::cout <<
"realSymbolicNumericIntegratePFD runtime: " << elapsed <<
" s" << std::endl;
811 fs.open(
"perftiming.txt",std::fstream::in | std::fstream::out | std::fstream::app);
812 fs << elapsed << std::endl;
818 temp.set(G.at(i),G.at(i+1));
825 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) {
832 std::vector<UnivariatePolynomialOverField> G;
834 temp.setVariableName(num.variable());
836 std::cout <<
"[realSymbolicNumericIntegratePFD (snIntPFD): Symbolic-Numeric Integration with BPAS and MPSolve]" << std::endl;
837 std::cout <<
"[Integration method: Hermite reduction, PFD integration]" << std::endl;
838 std::cout <<
"Starting..." << std::endl;
841 unsigned long long start;
845 std::cout <<
"--------------------------------------" << std::endl;
849 _realSNIntegrateSimplePFD<UnivariatePolynomialOverField,Field>(num,den,P,&G,lg,Lg,atn,Atn,prec,PROFILING,PFD_LOG_PART,ERROR_ANALYSIS);
852 stopTimer(&start,&elapsed);
853 std::cout <<
"--------------------------------------" << std::endl;
854 std::cout <<
"realSymbolicNumericIntegratePFD runtime: " << elapsed <<
" s" << std::endl;
856 fs.open(
"perftiming.txt",std::fstream::in | std::fstream::out | std::fstream::app);
857 fs << elapsed << std::endl;
863 temp.set(G.at(i),G.at(i+1));
913 std::vector<UnivariatePolynomialOverField> G;
914 for (
int i=0; i<g.size(); i++) {
915 G.push_back(g.at(i).num);
916 G.push_back(g.at(i).den);
918 _printFormalIntegral<UnivariatePolynomialOverField,Field>(num,den,P,G,U,S,
false, floatingPointPrinting,
false);
922 std::vector<UnivariatePolynomialOverField> G;
923 for (
int i=0; i<g.size(); i++) {
924 G.push_back(g.at(i).num);
925 G.push_back(g.at(i).den);
927 std::vector<UnivariatePolynomialOverField> empty;
928 _printIntegral<UnivariatePolynomialOverField,Field>(num,den,P,G,lg,Lg,atn,Atn,empty,
false, floatingPointPrinting,
false, outputFormatting);
931 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){
932 std::vector<UnivariatePolynomialOverField> G;
933 for (
int i=0; i<g.size(); i++) {
934 G.push_back(g.at(i).num);
935 G.push_back(g.at(i).den);
937 _printIntegral<UnivariatePolynomialOverField,Field>(num,den,P,G,lg,Lg,atn,Atn1,Atn2,
false, floatingPointPrinting,
false, outputFormatting);
940 void realSymbolicNumericIntegrate(
int prec) {
941 UnivariatePolynomialOverField P;
942 std::vector< UnivariateRationalFunction<UnivariatePolynomialOverField,Field> > g;
943 std::vector<Field> lg, atn;
944 std::vector<UnivariatePolynomialOverField> Lg, Atn1, Atn2;
946 realSymbolicNumericIntegrate(&P, &g, &lg, &Lg, &atn, &Atn1, &Atn2, prec);
947 printIntegral(P, g, lg, Lg, atn, Atn1, Atn2);
951 UnivariatePolynomialOverField P;
952 std::vector< UnivariateRationalFunction<UnivariatePolynomialOverField,Field> > g;
953 std::vector<UnivariatePolynomialOverField> U;
954 std::vector< SparseUnivariatePolynomial<UnivariatePolynomialOverField> > S;
956 integrate(&P, &g, &U, &S);
957 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:568
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:456
A sparsely represented univariate polynomial over an arbitrary ring.
Definition: BigPrimeField.hpp:21
void canonicalize()
Canonicalize this fraction, reducing terms as needed.
Definition: urationalfunction.h:419
An abstract class defining the interface of a rational function.
Definition: BPASRationalFunction.hpp:13
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:244
void print(std::ostream &ostream) const
Overload stream operator <<.
Definition: urationalfunction.h:505
ExpressionTree convertToExpressionTree() const
Convert this to an expression tree.
Definition: urationalfunction.h:493
UnivariateRationalFunction< UnivariatePolynomialOverField, Field > & operator%=(const UnivariateRationalFunction< UnivariatePolynomialOverField, Field > &b)
Assign *this to be the remainder of *this and b.
Definition: urationalfunction.h:585
UnivariateRationalFunction< UnivariatePolynomialOverField, Field > operator%(const UnivariateRationalFunction< UnivariatePolynomialOverField, Field > &b) const
Get the remainder of *this and b;.
Definition: urationalfunction.h:580
void zero()
Make *this ring element zero.
Definition: urationalfunction.h:434
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:535
UnivariatePolynomialOverField denominator() const
Get the fraction's denominator.
Definition: urationalfunction.h:248
UnivariateRationalFunction< UnivariatePolynomialOverField, Field > inverse() const
Get the inverse of *this.
Definition: urationalfunction.h:367
UnivariateRationalFunction< UnivariatePolynomialOverField, Field > quotient(const UnivariateRationalFunction< UnivariatePolynomialOverField, Field > &b) const
Get the quotient of *this and b.
Definition: urationalfunction.h:564
An arbitrary-precision Integer.
Definition: Integer.hpp:22
void one()
Make *this ring element one.
Definition: urationalfunction.h:441
UnivariateRationalFunction< UnivariatePolynomialOverField, Field > extendedEuclidean(const UnivariateRationalFunction< UnivariatePolynomialOverField, Field > &b, UnivariateRationalFunction< UnivariatePolynomialOverField, Field > *s=NULL, UnivariateRationalFunction< UnivariatePolynomialOverField, Field > *t=NULL) const
Perform the extended euclidean division on *this and b.
Definition: urationalfunction.h:572
bool isZero() const
Determine if *this ring element is zero, that is the additive identity.
Definition: urationalfunction.h:431
Integer euclideanSize() const
Get the euclidean size of *this.
Definition: urationalfunction.h:552
A univariate rational function templated by a unvariate polynomial over a field.
Definition: urationalfunction.h:73
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:438
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:556
Factors< UnivariateRationalFunction > squareFree() const
Compute squarefree factorization of *this.
Definition: urationalfunction.h:544