Basic Polynomial Algebra Subprograms (BPAS)  v. 1.652
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  mpz_class characteristic;
126  /**
127  * Construct the zero fraction function
128  *
129  * @param
130  **/
132  num;
133  den;
134  Domain c;
135  characteristic = c.characteristic;
136  }
137 
138  /**
139  * Copy constructor
140  *
141  * @param b: A rational function
142  **/
144  num = b.num;
145  den = b.den;
146  Domain c;
147  characteristic = c.characteristic;
148  }
149 
150  /**
151  * constructor with two parameter
152  *
153  * @param a: the numerator
154  * @param b: the denominator
155  **/
156  SmartFraction<Domain>(std::vector<Factor<Domain>> a, std::vector<Factor<Domain>> b){
157  num = a;
158  den = b;
159  Domain c;
160  characteristic = c.characteristic;
161  }
162 
163  SmartFraction<Domain>(Domain a, Domain b){
164  //cout << "print from constructor"<< endl;
165  //a.print(cout);
166  //cout << "num end" << endl;
167  //b.print(cout);
168  //cout << "den end" << endl;
169 
170  num = extractFactors(a);
171  den = extractFactors(b);
172 
173  //cout << "const : num size " << num.size() << endl;
174  //cout << "const : den size " << den.size() << endl;
175 
176  //cout << "num contain:" << endl;
177  //num[0].first.print(std::cout);
178  //cout << endl;
179  //normalize();
180 
181 
182  Domain c;
183  characteristic = c.characteristic;
184  }
185 
187 
188  void setNumerator(const std::vector<std::pair<Domain, int>>& b);
189  void setDenominator(const std::vector<std::pair<Domain, int>>& b);
190 
191  void set(const std::vector<std::pair<Domain, int>>& a, const std::vector<std::pair<Domain, int>>& b);
192 
193  Domain numerator() const;
194  Domain denominator() const;
195 
196  bool operator!=(const SmartFraction<Domain> &b) const;
197  bool operator==(const SmartFraction<Domain> &b) const;
198 
201 
202 
204 
205  void canonicalize();
206  void normalize();
207 
208  bool isZero() const;
209  bool isOne() const;
210  void zero();
211  void one();
218 
220 
222 
223  SmartFraction<Domain> operator^(long long int e) const;
224 
225  SmartFraction<Domain>& operator^=(long long int e);
226 
228  std::cerr << "SmartFraction<Domain>::squareFree NOT YET IMPLEMENTED" << std::endl;
229  //TODO
230  return Factors<SmartFraction<Domain>>(*this);
231  }
233  std::cerr << "SmartFraction<Domain>::convertToExpressionTree NOT YET IMPLEMENTED" << std::endl;
234  //TODO
235  return ExpressionTree();
236 
237  }
238 
239  void print(std::ostream& ostream) const;
248 
249 
250 
251 
252 };
253 
254  template <class Domain>
255  std::vector<Factor<Domain>> extractFactors(const Domain &p) {
256  std::vector<Factor<Domain>> ret;
257  Factors<Domain> v = p.squareFree();
258  if(v.size() == 1){
259  ret.emplace_back(v[0].first * v.ringElement(), 1);
260  return ret;
261  }
262 
263  Domain v0 = v.ringElement();
264  if(!v0.isOne()){
265  ret.emplace_back(v[0].first * v0, v[0].second);
266  } else {
267  ret.emplace_back(v[0].first, v[0].second);
268  }
269  for (int i = 1; i < v.size(); ++i){
270  if(!v[i].first.isOne()){
271  ret.emplace_back(v[i].first, v[i].second);
272  }
273  }
274 
275  return ret;
276  }
277 
278 
279 
280 
281  template <class Domain>
282  Domain convertToDomain(const std::vector<Factor<Domain>>& b){
283  Domain ret,temp;
284  long long int a;
285  ret.one();
286 
287  for (int i = 0; i < b.size(); ++i)
288  {
289  temp = b[i].first;
290  a = b[i].second;
291  //std::cout << "temp = " << temp << ", a = " << a << std::endl;
292  ret *= temp^a;
293  }
294 
295  return ret;
296  }
297 
298 
299 
300 
301 
302 
303 #endif
An abstract class defining the interface of a field of fractions.
Definition: BPASFieldOfFractions.hpp:16
void one()
Make *this ring element one.
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
Perofrm the extended euclidean division on *this and b.
Definition: SmartFraction.hpp:245
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:227
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:232
SmartFraction< Domain > operator^(long long int e) const
Exponentiation.
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.
virtual mpz_class characteristic()
The characteristic of this ring class.
Definition: BPASRing.hpp:87
void print(std::ostream &ostream) const
Print the Ring element.
Domain numerator() const
Get the fraction&#39;s numerator.
SmartFraction< Domain > euclideanSize() const
Get the euclidean size of *this.
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.