Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

expression.cc

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

Generated on Tue Nov 4 01:57:57 2003 for COCONUT API by doxygen1.2.18