1 //
2 //  func.h
3 //  Gravity
4 //
5 //  Created by Hijazi, Hassan on 25 Oct 18.
6 //
7 //
8 
9 #ifndef poly_h
10 #define poly_h
11 
12 #include <gravity/var.h>
13 #include <gravity/expr.h>
14 #include <stdio.h>
15 #include <map>
16 #include <iterator>
17 #include <queue>
18 #include <list>
19 #include <limits>
20 #include <set>
21 
22 using namespace std;
23 
24 namespace gravity {
25 
26 
27     class lterm{
28 
29     public:
30         shared_ptr<constant_>               _coef = nullptr; /**< Coefficient */
31         shared_ptr<param_>                  _p = nullptr; /**< Variable */
32         bool                                _sign = true; /**< True if +, false if - */
33 
lterm()34         lterm(){};
35 
lterm(lterm && t)36         lterm(lterm&& t){
37             *this = move(t);
38         };
39 
lterm(const lterm & t)40         lterm(const lterm& t){
41             *this = t;
42         };
43 
44 
45 //        lterm(shared_ptr<param_> p):lterm(true,p){
46 //        };
47 //
48 //
49 //        lterm(bool sign, shared_ptr<param_> p){
50 //            _coef = make_shared<constant<double>>(1);
51 //            _p = p;
52 //            _sign = sign;
53 //        };
54 
lterm(shared_ptr<constant_> coef,shared_ptr<param_> p)55         lterm(shared_ptr<constant_> coef, shared_ptr<param_> p):lterm(true,coef,p){};
56 
57         lterm(bool sign, shared_ptr<constant_> coef, shared_ptr<param_> p);
58 
reverse_sign()59         void reverse_sign() {
60             _sign = ! _sign;
61         }
62 
get_all_sign()63         Sign get_all_sign() const{
64             auto sign = _coef->get_all_sign();
65             if (sign==unknown_) {
66                 return unknown_;
67             }
68             if (_sign) {
69                 return sign;
70             }
71             if (sign==pos_) {
72                 return neg_;
73             }
74             if (sign==neg_) {
75                 return pos_;
76             }
77             return sign;
78         }
79 
80 
81         bool operator==(const lterm& l) const;
82         bool operator!=(const lterm& l) const;
83 
84         lterm& operator=(const lterm& l);
85         lterm& operator=(lterm&& l);
86 
87         string print_transposed(int prec) const;
88         string print_transposed(size_t idx, int prec) const;
89         string to_str() const;
90         string to_str(size_t ind, int prec) const;
91         string to_str(size_t ind, size_t inst, int prec) const;
92         void print(size_t ind) const;
93     };
94 
95 
96     /** A class to represent a quadratic term, e.g. 2xy or 3x^2. */
97     class qterm{
98 
99     public:
100         shared_ptr<constant_>                                        _coef = nullptr;
101         shared_ptr<pair<shared_ptr<param_>,shared_ptr<param_>>>      _p = nullptr;
102         bool                                                         _sign = true; /**< True if +, false if - */
103         bool                                                         _coef_p1_tr = false; /**< True if the qterm is (coef*p1)^T*p2 */
104 
qterm()105         qterm(){}
106 
qterm(const qterm & t)107         qterm(const qterm& t){
108             *this = t;
109         };
110 
qterm(qterm && t)111         qterm(qterm&& t){
112             *this = move(t);
113         };
114 
115 
116 //        qterm(shared_ptr<param_> p1, shared_ptr<param_> p2):qterm(true, p1, p2){};
117 
118 
qterm(shared_ptr<constant_> coef,shared_ptr<param_> p1,shared_ptr<param_> p2)119         qterm(shared_ptr<constant_> coef, shared_ptr<param_> p1, shared_ptr<param_> p2):qterm(true, coef, p1, p2){};
120 
121 //        qterm(bool sign, shared_ptr<param_> p1, shared_ptr<param_> p2):qterm(true, unit<type>(), p1, p2){};
122 
qterm(bool sign,shared_ptr<constant_> coef,shared_ptr<param_> p1,shared_ptr<param_> p2)123         qterm(bool sign, shared_ptr<constant_> coef, shared_ptr<param_> p1, shared_ptr<param_> p2){
124             _coef = coef;
125             _p = make_shared<pair<shared_ptr<param_>, shared_ptr<param_>>>(make_pair(p1,p2));
126             _sign = sign;
127 //            if (coef->_is_transposed){
128 //                p1->_is_vector=true;
129 //                p2->_is_vector=true;
130 //            }
131 //            if(p1->_is_vector){
132 //                coef->_is_transposed=true;
133 //                p2->_is_vector=true;
134 //            }
135 //            if(p2->_is_vector){
136 //                coef->_is_transposed=true;
137 //                p1->_is_vector=true;
138 //            }
139             if (coef->_is_transposed && p1->_is_transposed) {
140                 _coef_p1_tr = true;
141 //                throw invalid_argument("Check the transpose operator, there seems to be a dimension issue\n");
142             }
143 //            if (p1->_is_transposed) {
144 //                if (p1->get_dim() != p2->get_dim()) {
145 //                    throw invalid_argument("Check the transpose operator, there seems to be a dimension issue\n");
146 //                }
147 //            }
148             if (p2->_is_transposed) {
149                 throw invalid_argument("Check the transpose operator, there seems to be a dimension issue\n");
150             }
151         };
152 
reverse_sign()153         void reverse_sign() {
154             _sign = ! _sign;
155         }
156 
get_all_sign()157         Sign get_all_sign() const{
158             auto sign = _coef->get_all_sign();
159             if (sign==unknown_) {
160                 return unknown_;
161             }
162             if (_sign) {
163                 return sign;
164             }
165             if (sign==pos_) {
166                 return neg_;
167             }
168             if (sign==neg_) {
169                 return pos_;
170             }
171             return sign;
172         }
173 
get_convexity()174         Convexity get_convexity() const {
175             if(_p->first == _p->second){
176                 if (_sign && _coef->is_non_negative()) {
177                     return convex_;
178                 }
179                 if (_sign && _coef->is_non_positive()) {
180                     return concave_;
181                 }
182                 if (!_sign && _coef->is_non_negative()) {
183                     return concave_;
184                 }
185                 if (!_sign && _coef->is_non_positive()) {
186                     return convex_;
187                 }
188             }
189             return undet_;
190         }
191 
192 
193         bool operator==(const qterm& l) const;
194         bool operator!=(const qterm& l) const;
195 
196         qterm& operator=(const qterm& l);
197         qterm& operator=(qterm&& l);
198 
199         string to_str() const;
200         string to_str(size_t ind, int prec) const;
201         string to_str(size_t ind, size_t inst, int prec) const;
202         void print(size_t ind) const;
203         string print_transposed(int prec) const;
204         string print_transposed(size_t idx, int prec) const;
205         string print_row(size_t idx, int prec) const;
206     };
207 
208 
209     /** A class to represent a polynomial term, e.g. 2xyz or 3x^2y. */
210     class pterm{
211 
212     public:
213         shared_ptr<constant_>                                 _coef = nullptr;
214         shared_ptr<list<pair<shared_ptr<param_>, int>>>       _l = nullptr; /**< A polynomial term is represented as a list of pairs <param_*,int> where the first element points to the parameter and the second indicates the exponent */
215         bool                                                  _sign = true; /**< True if +, false if - */
216 
pterm()217         pterm(){}
218 
219 
pterm(bool sign,shared_ptr<constant_> coef,shared_ptr<param_> p,int exp)220         pterm(bool sign, shared_ptr<constant_> coef, shared_ptr<param_> p, int exp){
221             _coef = coef;
222             if (coef->_is_transposed && p->_is_transposed) {
223                 throw invalid_argument("Check the transpose operator, there seems to be a dimension issue\n");
224             }
225             if (p->_is_transposed) {
226                 throw invalid_argument("Check the transpose operator, there seems to be a dimension issue\n");
227             }
228             _l = make_shared<list<pair<shared_ptr<param_>, int>>>();
229             _l->push_back(make_pair<>(p, exp));
230             _sign = sign;
231         };
232 
pterm(const pterm & t)233         pterm(const pterm& t){
234             *this = t;
235         };
236 
pterm(pterm && t)237         pterm(pterm&& t){
238             *this = move(t);
239         };
240 
pterm(bool sign,shared_ptr<constant_> coef,shared_ptr<list<pair<shared_ptr<param_>,int>>> l)241         pterm(bool sign, shared_ptr<constant_> coef, shared_ptr<list<pair<shared_ptr<param_>, int>>> l){
242             shared_ptr<param_> p1 = nullptr;
243             shared_ptr<param_> p2 = nullptr;
244             for (auto it = l->begin(); it != l->end(); it++){
245                 p1 = it->first;
246                 if (p1->_is_transposed && next(it)!=l->end()) {
247                     p2 = next(it)->first;
248                     if (p1->get_dim() != p2->get_dim()) {
249                         throw invalid_argument("Check the transpose operator, there seems to be a dimension issue\n");
250                     }
251                 }
252                 if (p1->_is_transposed && next(it)==l->end()) {
253                     throw invalid_argument("Check the transpose operator, there seems to be a dimension issue\n");
254                 }
255             }
256             _coef = coef;
257             _l = l;
258             _sign = sign;
259         };
260 
261 
reverse_sign()262         void reverse_sign() {
263             _sign = ! _sign;
264         }
265 
get_all_sign()266         Sign get_all_sign() const{
267             auto sign = _coef->get_all_sign();
268             if (sign==unknown_) {
269                 return unknown_;
270             }
271             if (_sign) {
272                 return sign;
273             }
274             if (sign==pos_) {
275                 return neg_;
276             }
277             if (sign==neg_) {
278                 return pos_;
279             }
280             return sign;
281         }
282 
283         /* Return a new polynomial term excluding p */
284         pterm exclude(const shared_ptr<param_>& p) const;
285 
286         bool operator==(const pterm& l) const;
287         bool operator!=(const pterm& l) const;
288 
289         pterm& operator=(const pterm& l);
290         pterm& operator=(pterm&& l);
291         string print_poly_vars() const;
292         string print_poly_vars(size_t ind) const;
293         string print_poly_vars(size_t ind1, size_t ind2) const;
294         string to_str() const;
295         string to_str(size_t ind, int prec) const;
296         string to_str(size_t ind, size_t inst, int prec) const;
297         void print(size_t ind) const;
298 
299     };
300 
301 }
302 #endif /* poly_h */
303 
304