Basic Polynomial Algebra Subprograms (BPAS)  v. 1.791
SmartFraction.hpp
1 #ifndef _SMART_FRACTION_H_
2 #define _SMART_FRACTION_H_
3 
4 #include <iostream>
5 #include "BPASFieldOfFractions.hpp"
6 #include "../../include/RationalFunction/rationalfunction_euclideanmethods.h"
7 #include "../../include/RationalNumberPolynomial/mrpolynomial.h"
8 #include <algorithm>
9 #include <vector>
10 #include <utility>
11 #include "FactorRefinement.hpp"
12 
13 
14 /**
15  * A field of fractions templated by an arbitrary BPASGCDDomain making
16  * use of factor refinement.
17  */
18 template <class Domain>
19 class SmartFraction: public BPASFieldOfFractions<Domain, SmartFraction<Domain>> {
20 
21 private:
22  std::vector<Factor<Domain>> num;
23  std::vector<Factor<Domain>> den;
24  void smart_unitCanonical(const std::vector<Factor<Domain>>&A, std::vector<Factor<Domain>>*u, std::vector<Factor<Domain>>* C, std::vector<Factor<Domain>>* v) const{
25 
26  for (int i = 0; i < A.size(); ++i)
27  {
28  Domain curr_Domain = A[i].first;
29  int curr_exp = A[i].second;
30  Domain temp_u;
31  Domain temp_v;
32  Domain temp_C = curr_Domain.unitCanonical(&temp_u,&temp_v);
33  u->push_back(std::make_pair(temp_u,curr_exp));
34  C->push_back(std::make_pair(temp_C,curr_exp));
35  v->push_back(std::make_pair(temp_v,curr_exp));
36  }
37  return;
38  }
39  std::vector<Factor<Domain>> smart_gcd(const std::vector<Factor<Domain>>&A,const std::vector<Factor<Domain>>&B) const{
40  std::vector<Factor<Domain>> left, mid, right;
41  FactorRefinement::MergeRefineTwoSeq<Domain>(A,B,&left,&mid,&right);
42  return mid;
43  }
44 
45  static std::vector<Factor<Domain>> smart_add(const std::vector<Factor<Domain>>& A,const std::vector<Factor<Domain>>& B) {
46  Domain a;
47  a = convertToDomain(A);
48  Domain b;
49  b = convertToDomain(B);
50  a = a + b;
51  std::vector<Factor<Domain>> v;
52  v = extractFactors(a);
53  return v;
54  }
55 
56  static std::vector<Factor<Domain>> smart_sub(const std::vector<Factor<Domain>>&A,const std::vector<Factor<Domain>>&B) {
57  Domain a;
58  a = convertToDomain(A);
59  Domain b;
60  b = convertToDomain(B);
61  a = a - b;
62  std::vector<Factor<Domain>> v;
63  v = extractFactors(a);
64  return v;
65  }
66  static std::vector<Factor<Domain>> smart_mul(const std::vector<Factor<Domain>>&A,const std::vector<Factor<Domain>>&B) {
67 
68  std::vector<Factor<Domain>> v1,v2,v3;
69  FactorRefinement::MergeRefineTwoSeq<Domain>(A,B,&v1,&v2,&v3);
70  //catVectors(&v1,v2,v3);
71 
72  v1.insert(v1.end(),v2.begin(),v2.end());
73  v1.insert(v1.end(),v3.begin(),v3.end());
74  return v1;
75  }
76  std::vector<Factor<Domain>> smart_div(const std::vector<Factor<Domain>>&A,const std::vector<Factor<Domain>>&B) const{
77  std::vector<Factor<Domain>> v1,v2,v3;
78  FactorRefinement::MergeRefineTwoSeq<Domain>(A,B,&v1,&v2,&v3);
79  if(v3.size()!= 0){
80  cout << "BPAS error: in SmartFraction<Domain>, not exact division" <<endl;
81  exit(1);
82  }
83  return v1;
84  }
85 
86 
87 
88 
89 
90  static void smart_one(std::vector<Factor<Domain>>* b){
91  b->clear();
92  Domain one;
93  one.one();
94  b->push_back(std::make_pair(one,1));
95  }
96 
97  static std::vector<Factor<Domain>> smart_one(){
98  std::vector<Factor<Domain>> b;
99  Domain one;
100  one.one();
101  b.push_back(std::make_pair(one,1));
102  return b;
103 
104  }
105 
106  void smart_zero(std::vector<Factor<Domain>>& b){
107  b.clear();
108  }
109 
110  static bool smart_isOne(std::vector<Factor<Domain>>& b){
111  if(b.size() == 1 && b[0].first.isOne()){
112  return true;
113  }
114  else{
115  return false;
116  }
117 
118  }
119 
120 
121 
122 
123 
124 public:
125  /**
126  * Construct the zero fraction function
127  *
128  * @param
129  **/
131  num;
132  den;
133  Domain c;
134  }
135 
136  /**
137  * Copy constructor
138  *
139  * @param b: A rational function
140  **/
142  num = b.num;
143  den = b.den;
144  Domain c;
145  }
146 
147  /**
148  * constructor with two parameter
149  *
150  * @param a: the numerator
151  * @param b: the denominator
152  **/
153  SmartFraction<Domain>(std::vector<Factor<Domain>> a, std::vector<Factor<Domain>> b){
154  num = a;
155  den = b;
156  Domain c;
157  }
158 
159  SmartFraction<Domain>(Domain a, Domain b){
160  //cout << "print from constructor"<< endl;
161  //a.print(cout);
162  //cout << "num end" << endl;
163  //b.print(cout);
164  //cout << "den end" << endl;
165 
166  num = extractFactors(a);
167  den = extractFactors(b);
168 
169  //cout << "const : num size " << num.size() << endl;
170  //cout << "const : den size " << den.size() << endl;
171 
172  //cout << "num contain:" << endl;
173  //num[0].first.print(std::cout);
174  //cout << endl;
175  //normalize();
176 
177 
178  Domain c;
179  }
180 
182 
183  void setNumerator(const std::vector<std::pair<Domain, int>>& b);
184  void setDenominator(const std::vector<std::pair<Domain, int>>& b);
185 
186  void set(const std::vector<std::pair<Domain, int>>& a, const std::vector<std::pair<Domain, int>>& b);
187 
188  Domain numerator() const;
189  Domain denominator() const;
190 
191  bool operator!=(const SmartFraction<Domain> &b) const;
192  bool operator==(const SmartFraction<Domain> &b) const;
193 
196 
197 
199 
200  void canonicalize();
201  void normalize();
202 
203  bool isZero() const;
204  bool isOne() const;
205  void zero();
206  void one();
213 
215 
217 
218  SmartFraction<Domain> operator^(long long int e) const;
219 
220  SmartFraction<Domain>& operator^=(long long int e);
221 
223  std::cerr << "SmartFraction<Domain>::squareFree NOT YET IMPLEMENTED" << std::endl;
224  //TODO
225  return Factors<SmartFraction<Domain>>(*this);
226  }
228  std::cerr << "SmartFraction<Domain>::convertToExpressionTree NOT YET IMPLEMENTED" << std::endl;
229  //TODO
230  return ExpressionTree();
231 
232  }
233 
234  void print(std::ostream& ostream) const;
236  Integer euclideanSize() const;
241  std::cerr << "BPAS WARNING: SmartFraction::extendedEuclidean NOT YET IMPLEMENTED!" << std::endl;
242  return *this;
243  };
246 
247 
248 
249 
250 };
251 
252  template <class Domain>
253  std::vector<Factor<Domain>> extractFactors(const Domain &p) {
254  std::vector<Factor<Domain>> ret;
255  Factors<Domain> v = p.squareFree();
256  if(v.size() == 1){
257  ret.emplace_back(v[0].first * v.ringElement(), 1);
258  return ret;
259  }
260 
261  Domain v0 = v.ringElement();
262  if(!v0.isOne()){
263  ret.emplace_back(v[0].first * v0, v[0].second);
264  } else {
265  ret.emplace_back(v[0].first, v[0].second);
266  }
267  for (int i = 1; i < v.size(); ++i){
268  if(!v[i].first.isOne()){
269  ret.emplace_back(v[i].first, v[i].second);
270  }
271  }
272 
273  return ret;
274  }
275 
276 
277 
278 
279  template <class Domain>
280  Domain convertToDomain(const std::vector<Factor<Domain>>& b){
281  Domain ret,temp;
282  long long int a;
283  ret.one();
284 
285  for (int i = 0; i < b.size(); ++i)
286  {
287  temp = b[i].first;
288  a = b[i].second;
289  //std::cout << "temp = " << temp << ", a = " << a << std::endl;
290  ret *= temp^a;
291  }
292 
293  return ret;
294  }
295 
296 
297 
298 
299 
300 
301 #endif
An abstract class defining the interface of a field of fractions.
Definition: BPASFieldOfFractions.hpp:16
void one()
Make *this ring element one.
Integer euclideanSize() const
Get the euclidean size of *this.
SmartFraction< Domain > remainder(const SmartFraction< Domain > &b) const
Get the remainder of *this and b.
bool isZero() const
Determine if *this ring element is zero, that is the additive identity.
void zero()
Make *this ring element zero.
SmartFraction< Domain > & operator/=(const SmartFraction< Domain > &b)
Exact division assignment.
SmartFraction< Domain > inverse() const
Get the inverse of *this.
bool operator!=(const SmartFraction< Domain > &b) const
Inequality test,.
SmartFraction< Domain > & operator%=(const SmartFraction< Domain > &b)
Assign *this to be the remainder of *this and b.
bool isOne() const
Determine if *this ring element is one, that is the multiplication identity.
An ExpressionTree encompasses various forms of data that can be expressed generically as a binary tre...
Definition: ExpressionTree.hpp:17
SmartFraction< Domain > euclideanDivision(const SmartFraction< Domain > &b, SmartFraction< Domain > *q=NULL) const
Perform the eucldiean division of *this and b.
SmartFraction< Domain > operator%(const SmartFraction< Domain > &b) const
Get the remainder of *this and b;.
void canonicalize()
Canonicalize this fraction, reducing terms as needed.
SmartFraction< Domain > operator-() const
Negation.
SmartFraction< Domain > & operator^=(long long int e)
Exponentiation assignment.
SmartFraction< Domain > & operator-=(const SmartFraction< Domain > &b)
Subtraction assignment.
SmartFraction< Domain > extendedEuclidean(const SmartFraction< Domain > &b, SmartFraction< Domain > *s=NULL, SmartFraction< Domain > *t=NULL) const
Perform the extended euclidean division on *this and b.
Definition: SmartFraction.hpp:240
SmartFraction< Domain > quotient(const SmartFraction< Domain > &b) const
Get the quotient of *this and b.
Domain denominator() const
Get the fraction&#39;s denominator.
A simple data structure for encapsulating a collection of Factor elements.
Definition: Factors.hpp:95
Factors< SmartFraction< Domain > > squareFree() const
Compute squarefree factorization of *this.
Definition: SmartFraction.hpp:222
SmartFraction< Domain > gcd(const SmartFraction< Domain > &b) const
Get GCD of *this and other.
ExpressionTree convertToExpressionTree() const
Convert this to an expression tree.
Definition: SmartFraction.hpp:227
SmartFraction< Domain > operator^(long long int e) const
Exponentiation.
An arbitrary-precision Integer.
Definition: Integer.hpp:22
SmartFraction< Domain > operator+(const SmartFraction< Domain > &b) const
Addition.
bool operator==(const SmartFraction< Domain > &b) const
Equality test,.
SmartFraction< Domain > & operator+=(const SmartFraction< Domain > &b)
Addition assignment.
virtual Derived unitCanonical(Derived *u=NULL, Derived *v=NULL) const =0
Obtain the unit normal (a.k.a canonical associate) of an element.
A field of fractions templated by an arbitrary BPASGCDDomain making use of factor refinement...
Definition: SmartFraction.hpp:19
SmartFraction< Domain > unitCanonical(SmartFraction< Domain > *u=NULL, SmartFraction< Domain > *v=NULL) const
Obtain the unit normal (a.k.a canonical associate) of an element.
void print(std::ostream &ostream) const
Print the Ring element.
Domain numerator() const
Get the fraction&#39;s numerator.
SmartFraction< Domain > operator/(const SmartFraction< Domain > &b) const
Exact division.
SmartFraction< Domain > operator*(const SmartFraction< Domain > &b) const
Multiplication.
SmartFraction< Domain > & operator*=(const SmartFraction< Domain > &b)
Multiplication assignment.