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