00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00028 #include <coconut_config.h>
00029 #include <expression.h>
00030 #include <print_seq.h>
00031 #include <print_matrix.h>
00032 #include <writer_utils.h>
00033
00034 namespace coco {
00035
00036 extern const char *expr_names[];
00037
00038 bool expression_node::is(unsigned int __tp) const
00039 {
00040 bool _res = false;
00041
00042 if((__tp & ex_any) == 0 || (__tp & ex_any) == (unsigned int)ex_any)
00043 {
00044 if(__tp & ex_convex)
00045 {
00046 if(sem.property_flags.c_info == c_convex)
00047 _res = true;
00048 }
00049 else if(__tp & ex_concave)
00050 {
00051 if(sem.property_flags.c_info == c_concave)
00052 _res = true;
00053 }
00054 else
00055 _res = true;
00056 }
00057 else
00058 {
00059 if(__tp & ex_bound && __tp & ex_linear)
00060 {
00061 if(sem.degree == 1 || sem.property_flags.c_info == c_linear)
00062 _res = true;
00063 }
00064 if(__tp & ex_bound && !(__tp & ex_linear))
00065 {
00066 if(operator_type == EXPRINFO_VARIABLE)
00067 {
00068 if(f_bounds.inf() != -COCO_INF || f_bounds.sup() != COCO_INF)
00069 _res = true;
00070 }
00071 }
00072 if(__tp & ex_linear && !(__tp & ex_bound))
00073 {
00074 if((sem.degree == 1 || sem.property_flags.c_info == c_linear) &&
00075 operator_type != EXPRINFO_VARIABLE)
00076 _res = true;
00077 }
00078 if(__tp & ex_quadratic)
00079 {
00080 if(sem.degree == 2 && !(__tp & ex_convex && __tp & ex_concave))
00081 {
00082 if(__tp & ex_convex)
00083 {
00084 if(sem.property_flags.c_info == c_convex)
00085 _res = true;
00086 }
00087 else if(__tp & ex_concave)
00088 {
00089 if(sem.property_flags.c_info == c_concave)
00090 _res = true;
00091 }
00092 else
00093 _res = true;
00094 }
00095 }
00096 if(__tp & ex_polynomial)
00097 {
00098 if(sem.degree > 2 && !(__tp & ex_convex && __tp & ex_concave))
00099 {
00100 if(__tp & ex_convex)
00101 {
00102 if(sem.property_flags.c_info == c_convex)
00103 _res = true;
00104 }
00105 else if(__tp & ex_concave)
00106 {
00107 if(sem.property_flags.c_info == c_concave)
00108 _res = true;
00109 }
00110 else
00111 _res = true;
00112 }
00113 }
00114 if(__tp & ex_other)
00115 {
00116 if(sem.degree == -1 && sem.property_flags.c_info != c_linear &&
00117 !(__tp & ex_convex && __tp & ex_concave))
00118 {
00119 if(__tp & ex_convex)
00120 {
00121 if(sem.property_flags.c_info == c_convex)
00122 _res = true;
00123 }
00124 else if(__tp & ex_concave)
00125 {
00126 if(sem.property_flags.c_info == c_concave)
00127 _res = true;
00128 }
00129 else
00130 _res = true;
00131 }
00132 }
00133 }
00134
00135 if(_res)
00136 {
00137 if(__tp & ex_equality && !(__tp & (ex_bothbound|ex_inequality)) &&
00138 !f_bounds.is_thin())
00139 _res = false;
00140 if(__tp & ex_inequality && !(__tp & ex_equality) && f_bounds.is_thin())
00141 _res = false;
00142 if(__tp & ex_leftbound && f_bounds.inf() == -COCO_INF)
00143 _res = false;
00144 if(__tp & ex_rightbound && f_bounds.sup() == COCO_INF)
00145 _res = false;
00146 }
00147 if(_res || __tp == (unsigned int)ex_kj || __tp == (unsigned int)ex_org)
00148 {
00149 _res = true;
00150 if(__tp & ex_kj && __tp & ex_org)
00151 __tp &= ~(ex_kj|ex_org);
00152 if(__tp & ex_kj && !sem.kj_flag())
00153 _res = false;
00154 if(__tp & ex_org && sem.kj_flag())
00155 _res = false;
00156 }
00157 if(_res)
00158 {
00159 if(__tp & ex_redundant && __tp & ex_notredundant)
00160 __tp &= ~(ex_redundant|ex_notredundant);
00161 if(__tp & ex_redundant && !sem.redundancy())
00162 _res = false;
00163 if(__tp & ex_notredundant && sem.redundancy())
00164 _res = false;
00165 }
00166 if(_res)
00167 {
00168 if(__tp & ex_active_lo && __tp & ex_inactive_lo)
00169 __tp &= ~(ex_active_lo|ex_inactive_lo);
00170 if(__tp & ex_active_hi && __tp & ex_inactive_hi)
00171 __tp &= ~(ex_active_hi|ex_inactive_hi);
00172 if(__tp & ex_active_lo && sem.inactive_lo())
00173 _res = false;
00174 if(__tp & ex_inactive_lo && !sem.inactive_lo())
00175 _res = false;
00176 if(__tp & ex_active_hi && sem.inactive_hi())
00177 _res = false;
00178 if(__tp & ex_inactive_hi && !sem.inactive_hi())
00179 _res = false;
00180 }
00181 if(_res)
00182 {
00183 if(__tp & ex_integer && !sem.integer_flag())
00184 _res = false;
00185 }
00186 if(_res && __tp & (ex_exists|ex_forall|ex_free|ex_stochastic))
00187 {
00188 switch(sem.type())
00189 {
00190 case v_exists:
00191 _res = __tp & ex_exists ? 1 : 0;
00192 break;
00193 case v_forall:
00194 _res = __tp & ex_forall ? 1 : 0;
00195 break;
00196 case v_free:
00197 _res = __tp & ex_free ? 1 : 0;
00198 break;
00199 case v_stochastic:
00200 _res = __tp & ex_stochastic ? 1 : 0;
00201 break;
00202 }
00203 }
00204 return _res;
00205 }
00206
00207 std::ostream& operator<< (std::ostream& o, const expression_node& __x)
00208 {
00209 int precsave = o.precision(18);
00210
00211 switch(__x.operator_type)
00212 {
00213 case EXPRINFO_QUAD:
00214 case EXPRINFO_LOOKUP:
00215 case EXPRINFO_PWLIN:
00216 case EXPRINFO_SPLINE:
00217 case EXPRINFO_PWCONSTLC:
00218 case EXPRINFO_PWCONSTRC:
00219 case EXPRINFO_CMPROD:
00220 case EXPRINFO_CGFEM:
00221 o << "<M> " << __x.node_num << " D R " << __x.params.m().nrows() << ' '
00222 << __x.params.m().ncols() << '\n';
00223 for(int i = 0; i < __x.params.m().nrows(); ++i)
00224 {
00225 const linalg::matrix<double>::Row &r(__x.params.m()[i]);
00226 if(r.nnz() == 0) continue;
00227 if(9*r.nnz() < 8*r.size())
00228 {
00229 o << "<r> " << __x.node_num << ' ' << i << ' ' << r.nz_struct() <<
00230 ": ";
00231 linalg::matrix<double>::Row::const_iterator _x(r.begin());
00232 o << double_out(*_x);
00233 for(++_x; _x != r.end(); ++_x)
00234 o << ',' << double_out(*_x);
00235 }
00236 else
00237 {
00238 o << "<R> " << __x.node_num << ' ' << i << ' ' << double_out(r[0]);
00239 for(int j = 1; j < r.size(); ++j)
00240 o << ',' << double_out(r[j]);
00241 }
00242 o << '\n';
00243 }
00244 break;
00245
00246 case EXPRINFO_LEVEL:
00247 o << "<M> " << __x.node_num << " I R " << __x.params.im().nrows() << ' '
00248 << __x.params.im().ncols() << '\n';
00249 for(int i = 0; i < __x.params.im().nrows(); ++i)
00250 {
00251 const linalg::matrix<interval>::Row &r(__x.params.im()[i]);
00252 if(r.nnz() == 0) continue;
00253 if(17*r.nnz() < 16*r.size())
00254 {
00255 o << "<r> " << __x.node_num << ' ' << i << ' ' << r.nz_struct() <<
00256 ": ";
00257 linalg::matrix<interval>::Row::const_iterator _x = r.begin();
00258 __wr_interval(o, *_x);
00259 for(++_x; _x != r.end(); ++_x)
00260 {
00261 o << ',';
00262 __wr_interval(o, *_x);
00263 }
00264 }
00265 else
00266 {
00267 o << "<R> " << __x.node_num << ' ' << i << ' ';
00268 __wr_interval(o, r[0]);
00269 for(int j = 1; j < r.size(); ++j)
00270 {
00271 o << ',';
00272 __wr_interval(o, r[j]);
00273 }
00274 }
00275 o << '\n';
00276 }
00277 break;
00278
00279 case EXPRINFO_DET:
00280 case EXPRINFO_COND:
00281 case EXPRINFO_PSD:
00282 case EXPRINFO_MPROD:
00283 case EXPRINFO_FEM:
00284 o << "<M> " << __x.node_num << " N R " << __x.params.nm().nrows() << ' '
00285 << __x.params.nm().ncols() << '\n';
00286 for(int i = 0; i < __x.params.nm().nrows(); ++i)
00287 {
00288 const linalg::matrix<int>::Row &r(__x.params.nm()[i]);
00289 if(r.nnz() == 0) continue;
00290 if(2*r.nnz() < r.size())
00291 {
00292 o << "<r> " << __x.node_num << ' ' << i << ' ' << r.nz_struct() <<
00293 ": ";
00294 linalg::matrix<int>::Row::const_iterator _x(r.begin());
00295 o << *_x;
00296 for(++_x; _x != r.end(); ++_x)
00297 o << ',' << *_x;
00298 }
00299 else
00300 {
00301 o << "<R> " << __x.node_num << ' ' << i << ' ' << r[0];
00302 for(int j = 1; j < r.size(); ++j)
00303 o << ',' << r[j];
00304 }
00305 o << '\n';
00306 }
00307 break;
00308 default:
00309
00310 break;
00311 }
00312
00313 o << "<" << __x.node_num << "> ";
00314
00315 o << "s " << __x.sem << ": ";
00316
00317 if(__x.f_bounds.inf() != -COCO_INF || __x.f_bounds.sup() != COCO_INF)
00318 {
00319 o << "b ";
00320 __wr_interval(o, __x.f_bounds);
00321 o << ": ";
00322 }
00323
00324 if(__x.is_var && __x.operator_type < EXPRINFO_VARIABLE)
00325 {
00326 int fs=0;
00327
00328 o << "v ";
00329 for(std::vector<unsigned int>::const_iterator i = __x.var_idx.begin();
00330 i != __x.var_idx.end(); i++)
00331 {
00332 if(fs)
00333 o << ',';
00334 o << *i;
00335 fs = 1;
00336 }
00337 o << ": ";
00338 }
00339
00340 switch(__x.operator_type)
00341 {
00342 case EXPRINFO_GHOST:
00343 o << "G " << (__x.params.nb() ? 'T' : 'F');
00344 break;
00345
00346 case EXPRINFO_CONSTANT:
00347 o << "C ";
00348 if(__x.params.is_allocated())
00349 {
00350 int f=0;
00351 const std::vector<double>& __xxvd = __x.params.d();
00352
00353 for(std::vector<double>::const_iterator __i = __xxvd.begin();
00354 __i != __xxvd.end(); ++__i)
00355 {
00356 if(f)
00357 o << ',';
00358 o << double_out(*__i) << " ";
00359 f = 1;
00360 }
00361 }
00362 else
00363 o << double_out(__x.params.nd()) << " ";
00364 break;
00365
00366 case EXPRINFO_VARIABLE:
00367 o << "V " << __x.params.nn();
00368 break;
00369
00370 case EXPRINFO_SUM:
00371 case EXPRINFO_PROD:
00372 case EXPRINFO_MAX:
00373 case EXPRINFO_MIN:
00374 case EXPRINFO_INVERT:
00375 case EXPRINFO_SQUARE:
00376 case EXPRINFO_SQROOT:
00377 case EXPRINFO_ABS:
00378 case EXPRINFO_POW:
00379 case EXPRINFO_DIV:
00380 case EXPRINFO_EXP:
00381 case EXPRINFO_LOG:
00382 case EXPRINFO_SIN:
00383 case EXPRINFO_COS:
00384 case EXPRINFO_ALLDIFF:
00385 o << "d " << double_out(__x.params.nd()) << ": ";
00386 break;
00387
00388 case EXPRINFO_MONOME:
00389 case EXPRINFO_NEIGHBOR:
00390 case EXPRINFO_NOGOOD:
00391 o << "n ";
00392 {
00393 int f=0;
00394 const std::vector<int>& __xxvd = __x.params.n();
00395
00396 for(std::vector<int>::const_iterator __i = __xxvd.begin();
00397 __i != __xxvd.end(); ++__i)
00398 {
00399 if(f)
00400 o << ',';
00401 o << *__i << " ";
00402 f = 1;
00403 }
00404 }
00405 break;
00406
00407 case EXPRINFO_POLY:
00408 o << "d ";
00409 {
00410 int f=0;
00411 const std::vector<double>& __xxvd = __x.params.d();
00412
00413 for(std::vector<double>::const_iterator __i = __xxvd.begin();
00414 __i != __xxvd.end(); ++__i)
00415 {
00416 if(f)
00417 o << ',';
00418 o << double_out(*__i) << " ";
00419 f = 1;
00420 }
00421 }
00422 break;
00423
00424 case EXPRINFO_IN:
00425 case EXPRINFO_AND:
00426 case EXPRINFO_OR:
00427 case EXPRINFO_IMPLIES:
00428 case EXPRINFO_COUNT:
00429 case EXPRINFO_INTEGRAL:
00430 o << "i ";
00431 {
00432 int f=0;
00433 const std::vector<interval>& __xxvd = __x.params.i();
00434
00435 for(std::vector<interval>::const_iterator __i = __xxvd.begin();
00436 __i != __xxvd.end(); ++__i)
00437 {
00438 if(f)
00439 o << ',';
00440 __wr_interval(o,*__i);
00441 o << " ";
00442 f = 1;
00443 }
00444 }
00445 break;
00446
00447 case EXPRINFO_INTPOWER:
00448 case EXPRINFO_LIN:
00449 o << "n " << __x.params.nn() << ": ";
00450 break;
00451
00452 case EXPRINFO_ATAN2:
00453 case EXPRINFO_MEAN:
00454 case EXPRINFO_EXPECTATION:
00455 case EXPRINFO_SCPROD:
00456 case EXPRINFO_NORM:
00457 case EXPRINFO_RE:
00458 case EXPRINFO_IM:
00459 case EXPRINFO_ARG:
00460 case EXPRINFO_CPLXCONJ:
00461 break;
00462
00463 case EXPRINFO_QUAD:
00464 case EXPRINFO_LOOKUP:
00465 case EXPRINFO_PWLIN:
00466 case EXPRINFO_SPLINE:
00467 case EXPRINFO_PWCONSTLC:
00468 case EXPRINFO_PWCONSTRC:
00469 case EXPRINFO_CMPROD:
00470 case EXPRINFO_CGFEM:
00471 case EXPRINFO_LEVEL:
00472 case EXPRINFO_DET:
00473 case EXPRINFO_COND:
00474 case EXPRINFO_PSD:
00475 case EXPRINFO_MPROD:
00476 case EXPRINFO_FEM:
00477 o << "m " << __x.node_num << ": ";
00478 break;
00479
00480 case EXPRINFO_IF:
00481 case EXPRINFO_NOT:
00482 o << "i ";
00483 __wr_interval(o, __x.params.ni());
00484 o << ": ";
00485 break;
00486
00487 case EXPRINFO_GAUSS:
00488 o << "d " << double_out(__x.params.d()[0]) << "," <<
00489 double_out(__x.params.d()[1]) << ": ";
00490 break;
00491
00492 default:
00493 std::cerr << "Warning: printing of general functions not yet implemented!\n";
00494 break;
00495 }
00496
00497 if(__x.operator_type < EXPRINFO_VARIABLE)
00498 o << expr_names[-__x.operator_type];
00499 else if(__x.operator_type > 0)
00500 o << "f(" << __x.operator_type << ')';
00501
00502 o << std::endl;
00503 o.precision(precsave);
00504 return o;
00505 }
00506
00507 }