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